1

我刚刚重新开始学习 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]);
}
4

2 回答 2

1

你做 :

cells[i] = *newList(N);

它将每个元素设置cells为由 动态分配的列表的副本newList。所以newList动态分配一个列表,然后你将指针指向动态分配的List,取消引用它,然后将它复制到cells[i]. 因此,稍后当您转到free()每个元素时:

free(&cells[i]);

它不起作用,因为其中的每个元素cells[i]都是List,而不是List *由 分配的(列表指针)malloc()

所以你有两个选择。一个(坏的)是删除最后free()一行,因为没有什么可以释放的。但是,这只是掩盖了一个更大的问题,即您现在有内存泄漏,因为您无法返回并释放使用List创建的动态分配的 s 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]);
于 2013-04-11T02:18:17.023 回答
0

问题是您正在分配一个列表数组,将列表的全部内容复制到数组元素中,然后尝试释放它们。原始分配的 List 记录是内存泄漏,并且 free 调用确实试图释放未 malloc 的内存(或者更准确地说是 malloc 在一个大块中)。

你想要一个指向指针的数组来保存你的列表:

/* 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);
于 2013-04-11T02:15:14.723 回答