C malloc释放结构时出错
我刚刚重新开始学习C,但我对一些内存管理细节感到困惑。 我要走了 未分配正在释放的指针。。。流产陷阱 对于下面的代码。我真的每个malloc需要1个免费的吗?为什么我的代码错了?C malloc释放结构时出错,c,memory-management,struct,malloc,free,C,Memory Management,Struct,Malloc,Free,我刚刚重新开始学习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
谢谢
#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]);
}
#定义N 9
类型定义结构
{
int最大列表大小;
整数长度;
int*ini;
}名单;
/*分配新列表及其数据*/
列表*新列表(整数大小)
{
List*List=malloc(sizeof(List));
列表->最大列表大小=大小;
列表->长度=0;
列表->ini=malloc(sizeof(int)*大小);
退货清单;
}
/*在列表中添加一些值*/
无效地址列表(列表*列表,int val)
{
如果(列表->长度<列表->最大列表大小)
列表->ini[列表->长度++]=val;
其他的
fprintf(stderr,“错误:add():列表已满。\n”);
}
/*获取N*N个列表的数组malloc-ed列表*/
List*gridList()
{
int i,j;
列表*单元格=malloc(sizeof(列表)*N*N);
对于(i=0;i
问题是您正在分配一个列表数组,将列表的全部内容复制到数组元素中,然后尝试释放它们。最初分配的列表记录是内存泄漏,而空闲调用实际上是试图释放未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);
/*获取N*N个列表的数组malloc-ed列表*/
列表**gridList()
{
int i,j;
//这里有零钱
列表**单元格=malloc(sizeof(List*)*N*N);
对于(i=0;i cells[i]=newList(N);///ini);//问题是您正在分配一个列表数组,将列表的完整内容复制到数组元素中,然后尝试释放它们。原始分配的列表记录是内存泄漏,而空闲调用确实在尝试释放未被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);
/*获取N*N个列表的数组malloc-ed列表*/
列表**gridList()
{
int i,j;
//这里有零钱
列表**单元格=malloc(sizeof(List*)*N*N);
对于(i=0;i
cells[i] = *newList(N);
它将单元格
中的每个元素设置为新列表
动态分配的列表的副本。因此新列表
动态分配一个列表,然后您将指针指向该动态分配的列表
,取消引用它,并将其复制到单元格[i]
。因此,稍后当您转到free()
每个元素:
free(&cells[i]);
它不起作用,因为单元格[i]
中的每个元素都是列表,而不是malloc()
分配的列表*
(列表指针)
所以你有两个选择。一个(坏的选择)是删除最后一行free()
,因为没有任何东西可以释放。然而,这只是掩盖了一个更大的问题,即你现在有内存泄漏,因为你不能返回并释放用newList()
创建的动态分配的列表
相反,您可能希望有一个指向列表的指针数组,您可以将其更改为:
List **cells = malloc(sizeof(List*) * N * N);
因此,cells[i]
引用了一个List*
newList()
返回这样一个指针,所以您可以将该行更改为:
cells[i] = newList(N);
addList(cells[i], j + 1);
类似地,addList()
采用这样一个指针,因此您只需将该行更改为:
cells[i] = newList(N);
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]);
你可以:
cells[i] = *newList(N);
它将单元格
中的每个元素设置为新列表
动态分配的列表的副本。因此新列表
动态分配一个列表,然后您将指针指向该动态分配的列表
,取消引用它,并将其复制到单元格[i]
。因此,稍后当您转到free()
每个元素:
free(&cells[i]);
它不起作用,因为单元格[i]
中的每个元素都是列表,而不是malloc()
分配的列表*
(列表指针)
所以你有两个选择。一个(坏的选择)是删除最后一行free()
,因为没有任何东西可以释放。然而,这只是掩盖了一个更大的问题,即你现在有内存泄漏,因为你不能返回并释放用newList()
创建的动态分配的列表
相反,您可能希望有一个指向列表的指针数组,您可以将其更改为:
List **cells = malloc(sizeof(List*) * N * N);
因此,cells[i]
引用了一个List*
newList()
返回这样一个指针,所以您可以将该行更改为:
cells[i] = newList(N);
addList(cells[i], j + 1);
类似地,addList()
采用这样一个指针,因此您只需将该行更改为:
cells[i] = newList(N);
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) 代码不需要是“完整的”?2)3)我知道Java.C是一种很好的语言。但是@Beta关于小的、完整的、可编译的例子的观点非常好。如果你听从他的建议,你更有可能得到答案。@Beta:第1点和第2点非常好。至于第3点,这不是语言战争的地方。正如我所说的,代码是微不足道的对于一个“C类人”,这就是为什么我没有两者兼而有之