我刚刚重新开始学习C,但我真的很困惑一些内存管理细节。 我正在
被释放的指针未被分配...中止陷阱
代码如下。我真的每个malloc需要1个免费?为什么我的代码错了?
谢谢!
#define N 9
typedef struct
{
int MAX_LIST_SIZE;
int length;
int *ini;
}List;
/* allocates new List and its data */
List *newList(int size)
{
List *list = malloc(sizeof(List));
list->MAX_LIST_SIZE = size;
list->length = 0;
list->ini = malloc(sizeof(int) * size);
return list;
}
/* add some value to the list */
void addList(List *list, int val)
{
if (list->length < list->MAX_LIST_SIZE)
list->ini[list->length++] = val;
else
fprintf(stderr, "Error: add(): List is full.\n");
}
/* get an array of N*N lists malloc-ed Lists */
List *gridList()
{
int i, j;
List *cells = malloc(sizeof(List) * N * N);
for (i = 0; i < N * N; i++)
{
/* malloc is called inside NewList()*/
cells[i] = *newList(N);
for (j = 0; j < N; j++)
addList(&cells[i], j + 1);
}
return cells;
}
/* inside main */
List *cells = gridList();
/* use cells ... */
/* free */
for (i = 0; i < N * N; i++)
{
free(cells[i].ini);
/* line below causes CRASH */
free(&cells[i]);
}
答案 0 :(得分:1)
你这样做:
cells[i] = *newList(N);
将cells
中的每个元素设置为newList
动态分配的列表副本。因此newList
动态分配列表,然后将指针指向动态分配的List
,取消引用它,并将其复制到cells[i]
。所以,稍后当你转到free()
每个元素时:
free(&cells[i]);
它不起作用,因为cells[i]
中的每个元素都是List
,而不是List *
分配的malloc()
(列表指针)。
所以你有两个选择。一个(坏的)是删除最后的free()
行,因为没有什么可以免费的。但是,这只是掩盖了一个更大的问题,即您现在有内存泄漏,因为您无法返回并释放使用List
创建的动态分配的newList()
。
相反,您可能希望有一个指向列表的指针数组,您可以将其更改为:
List **cells = malloc(sizeof(List*) * N * N);
以便cells[i]
引用List *
。 newList()
返回这样的指针,因此您可以将该行更改为:
cells[i] = newList(N);
类似地,addList()
采用这样的指针,因此您只需将该行更改为:
addList(cells[i], j + 1);
因为&cells[i]
会将指针的地址传递给它,这不是你想要的。
最后,将自由语句更改为:
free(cells[i]->ini); // ->init because cells[i] is now a pointer to a List, List *
free(cells[i]);
答案 1 :(得分:0)
问题是你正在分配一个列表数组,将列表的全部内容复制到数组元素中,然后尝试释放它们。原始分配的List记录是一个内存泄漏,并且免费调用确实试图释放没有malloc'ed的内存(或者更确切地说是在一个大块中malloc'ed)。
你想要一个指向指针的数组来保存你的列表:
/* get an array of N*N lists malloc-ed Lists */
List **gridList()
{
int i, j;
// VV note change here
List **cells = malloc(sizeof(List*) * N * N);
for (i = 0; i < N * N; i++)
{
/* malloc is called inside NewList()*/
cells[i] = newList(N); // << Note change here.
for (j = 0; j < N; j++)
addList(cells[i], j + 1);
}
return cells;
}
/* free */
for (i = 0; i < N * N; i++)
{
free(cells[i]->ini); // << and here
/* line below causes CRASH */
free(cells[i]); // << and here
}
free(cells);