用于动态分配内存(基于结构)的程序 运行 在不同的 IDE 上不同
Program for dynamically allocating memory (structure based) running differently on different IDEs
我正在编写一个程序来创建一个用于创建列表的结构,但是我遇到了双重释放或损坏错误。我知道链表会是一个更好的实现,但我想知道我在这里做错了什么。该代码在我的 IDE 中运行完美,但显示
在 Ubuntu 的终端上使用 GCC 在 运行 上出现上述错误。
/* Implements an employee structure having name and company name
and can take new employees, delete last employee and display entire list of employees */
#include <stdio.h>
#include <stdlib.h>
// defining structure employee
typedef struct emp
{
char name[20];
char company[20];
}emp;
int p = 0, size = 0;
void create(emp *);
void del(emp *);
void display(emp *);
int main(void)
{
emp *buffer = malloc(sizeof(emp));
if (buffer == NULL)
{
printf("Error");
exit(1);
}
int n = 0;
do
{
printf("The options are:\n");
printf("1. Add employee\n");
printf("2. Delete employee\n");
printf("3. Display employee\n");
printf("4. Exit\n");
printf("Enter from 1 to 4:");
scanf("%d",&n);
if (n == 1)
{
create(buffer);
}
else if (n == 2)
{
del(buffer);
}
else if (n == 3)
{
display(buffer);
}
}while(n != 4);
free(buffer);
return 0;
}
void create(emp *buffer)
{
size++;
if (p != 0)
{
buffer = realloc(buffer, size * sizeof(emp));
if (buffer == NULL)
{
printf("Error");
exit(1);
}
}
printf("Enter:");
scanf("%s%s", (buffer + size - 1)->name, (buffer + size - 1)->company);
p++;
}
void del(emp *buffer)
{
// deletes only last node
size--;
buffer = realloc(buffer, size * sizeof(emp));
if (buffer == NULL)
{
printf("Error");
exit(1);
}
}
void display(emp *buffer)
{
int k = 0;
for (k = 1; k <= size; k++)
{
printf("Name:%s\n",(buffer + k - 1)->name);
printf("Company:%s\n",(buffer + k - 1)->company);
}
}
更新:
我 运行 valgrind 并得到以下信息,但无法理解我在哪里重新分配不正确。
==3322== Invalid free() / delete / delete[] / realloc()
==3322== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3322== by 0x4008C9: create (in /home/akshay/Data/practice/a.out)
==3322== by 0x40081C: main (in /home/akshay/Data/practice/a.out)
==3322== Address 0x5203040 is 0 bytes inside a block of size 40 free'd
==3322== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3322== by 0x4008C9: create (in /home/akshay/Data/practice/a.out)
==3322== by 0x40081C: main (in /home/akshay/Data/practice/a.out)
==3322== Block was alloc'd at
==3322== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3322== by 0x400786: main (in /home/akshay/Data/practice/a.out)
==3322==
Error==3322==
==3322== HEAP SUMMARY:
==3322== in use at exit: 80 bytes in 1 blocks
==3322== total heap usage: 5 allocs, 4 frees, 2,288 bytes allocated
==3322==
==3322== LEAK SUMMARY:
==3322== definitely lost: 80 bytes in 1 blocks
==3322== indirectly lost: 0 bytes in 0 blocks
==3322== possibly lost: 0 bytes in 0 blocks
==3322== still reachable: 0 bytes in 0 blocks
==3322== suppressed: 0 bytes in 0 blocks
==3322== Rerun with --leak-check=full to see details of leaked memory
==3322==
==3322== For counts of detected and suppressed errors, rerun with: -v
==3322== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
您正在按值将缓冲区传递给 create
和 del
,因此您对其所做的任何更改都不会反映出来。所以 free
得到 buffer
的旧值。您有 3 个选项 -
O1 :像您对大小所做的那样使缓冲区成为全局缓冲区,并且不要将其作为参数传递。简单但不建议。
O2 : return 来自 del
和 create
的 buffer
的新值。然后在调用 do
buffer = del(buffer);
O3 : 传递一个指向buffer的指针而不是buffer并在里面修改。您的原型将更改为
void create(emp ** buffer);
而且你必须在 create
中的每个地方使用 *buffer
(del
也是如此)。
此外,呼叫将更改为
create(&buffer);
这个有点复杂但是最"correct"一个
希望能帮助您理解问题。
我正在编写一个程序来创建一个用于创建列表的结构,但是我遇到了双重释放或损坏错误。我知道链表会是一个更好的实现,但我想知道我在这里做错了什么。该代码在我的 IDE 中运行完美,但显示 在 Ubuntu 的终端上使用 GCC 在 运行 上出现上述错误。
/* Implements an employee structure having name and company name
and can take new employees, delete last employee and display entire list of employees */
#include <stdio.h>
#include <stdlib.h>
// defining structure employee
typedef struct emp
{
char name[20];
char company[20];
}emp;
int p = 0, size = 0;
void create(emp *);
void del(emp *);
void display(emp *);
int main(void)
{
emp *buffer = malloc(sizeof(emp));
if (buffer == NULL)
{
printf("Error");
exit(1);
}
int n = 0;
do
{
printf("The options are:\n");
printf("1. Add employee\n");
printf("2. Delete employee\n");
printf("3. Display employee\n");
printf("4. Exit\n");
printf("Enter from 1 to 4:");
scanf("%d",&n);
if (n == 1)
{
create(buffer);
}
else if (n == 2)
{
del(buffer);
}
else if (n == 3)
{
display(buffer);
}
}while(n != 4);
free(buffer);
return 0;
}
void create(emp *buffer)
{
size++;
if (p != 0)
{
buffer = realloc(buffer, size * sizeof(emp));
if (buffer == NULL)
{
printf("Error");
exit(1);
}
}
printf("Enter:");
scanf("%s%s", (buffer + size - 1)->name, (buffer + size - 1)->company);
p++;
}
void del(emp *buffer)
{
// deletes only last node
size--;
buffer = realloc(buffer, size * sizeof(emp));
if (buffer == NULL)
{
printf("Error");
exit(1);
}
}
void display(emp *buffer)
{
int k = 0;
for (k = 1; k <= size; k++)
{
printf("Name:%s\n",(buffer + k - 1)->name);
printf("Company:%s\n",(buffer + k - 1)->company);
}
}
更新: 我 运行 valgrind 并得到以下信息,但无法理解我在哪里重新分配不正确。
==3322== Invalid free() / delete / delete[] / realloc()
==3322== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3322== by 0x4008C9: create (in /home/akshay/Data/practice/a.out)
==3322== by 0x40081C: main (in /home/akshay/Data/practice/a.out)
==3322== Address 0x5203040 is 0 bytes inside a block of size 40 free'd
==3322== at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3322== by 0x4008C9: create (in /home/akshay/Data/practice/a.out)
==3322== by 0x40081C: main (in /home/akshay/Data/practice/a.out)
==3322== Block was alloc'd at
==3322== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3322== by 0x400786: main (in /home/akshay/Data/practice/a.out)
==3322==
Error==3322==
==3322== HEAP SUMMARY:
==3322== in use at exit: 80 bytes in 1 blocks
==3322== total heap usage: 5 allocs, 4 frees, 2,288 bytes allocated
==3322==
==3322== LEAK SUMMARY:
==3322== definitely lost: 80 bytes in 1 blocks
==3322== indirectly lost: 0 bytes in 0 blocks
==3322== possibly lost: 0 bytes in 0 blocks
==3322== still reachable: 0 bytes in 0 blocks
==3322== suppressed: 0 bytes in 0 blocks
==3322== Rerun with --leak-check=full to see details of leaked memory
==3322==
==3322== For counts of detected and suppressed errors, rerun with: -v
==3322== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
您正在按值将缓冲区传递给 create
和 del
,因此您对其所做的任何更改都不会反映出来。所以 free
得到 buffer
的旧值。您有 3 个选项 -
O1 :像您对大小所做的那样使缓冲区成为全局缓冲区,并且不要将其作为参数传递。简单但不建议。
O2 : return 来自 del
和 create
的 buffer
的新值。然后在调用 do
buffer = del(buffer);
O3 : 传递一个指向buffer的指针而不是buffer并在里面修改。您的原型将更改为
void create(emp ** buffer);
而且你必须在 create
中的每个地方使用 *buffer
(del
也是如此)。
此外,呼叫将更改为
create(&buffer);
这个有点复杂但是最"correct"一个
希望能帮助您理解问题。