简体   繁体   English

C malloc错误释放结构

[英]C malloc error freeing struct

I've just re-start learning C, but i'm really confused with some memory management details. 我刚刚重新开始学习C,但是我确实对一些内存管理细节感到困惑。 I'm getting 我越来越

pointer being freed was not allocated ... Abort trap 没有分配要释放的指针...中止陷阱

for the code below. 用于以下代码。 Do i really need 1 free per malloc? 真的需要每个malloc免费吗? Why my code is wrong? 为什么我的代码是错误的?
Thanks! 谢谢!

#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]);
}

You do : 你做 :

cells[i] = *newList(N);

which sets each element in cells to a copy of the list dynamically allocated by newList . 它将单元cells中的每个元素设置为由newList动态分配的列表的副本。 So newList dynamically allocates a list, then you take the pointer to that dynamically allocated List , dereference it, and copy it into cells[i] . 因此, newList动态分配一个列表,然后使用指向该动态分配的List的指针,对其进行取消引用,然后将其复制到cells[i] So then later on when you go to free() each element: 因此,稍后在您使用free()每个元素时:

free(&cells[i]);

It doesn't work because each element in cells[i] is a List , not a List * (list pointer) allocated by malloc() . 这是行不通的,因为cells[i]中的每个元素都是一个List ,而不是malloc()分配的List * (列表指针malloc()

So you have two options. 因此,您有两个选择。 One (bad one) is to just remove that last free() line since there's nothing to free. 一个(不好的)方法是删除最后一个free()行,因为没有什么要释放的。 However, this just covers up a larger problem which is that you now have memory leaks because you can't go back and free the dynamically allocated List s created with newList() . 但是,这掩盖了一个更大的问题,即您现在有内存泄漏,因为您无法返回并释放由newList()创建的动态分配的List

Instead it's likely you want to have an array of pointers to the lists, which you can do by changing it to: 相反,您可能希望拥有一个指向列表的指针数组,可以通过将其更改为:

List **cells = malloc(sizeof(List*) * N * N);

so that cells[i] refers to a List * . 因此cells[i]引用List * newList() returns such a pointer, so you would change that line to: newList()返回这样的指针,因此您可以将该行更改为:

cells[i] = newList(N);

similarly, addList() takes such a pointer, so you'd simply change that line to: 同样, addList()采用这样的指针,因此您只需将该行更改为:

addList(cells[i], j + 1);

since &cells[i] would pass it the address of the pointer, which is not what you want. 因为&cells[i]会将指针的地址传递给它,这不是您想要的。

Finally, change the free statements to: 最后,将free语句更改为:

free(cells[i]->ini); // ->init because cells[i] is now a pointer to a List, List *
free(cells[i]);

The problem is you are allocating an array of lists, copying the full contents of your lists into the array elements, and then trying to free them. 问题是您要分配一个列表数组,将列表的全部内容复制到数组元素中,然后尝试释放它们。 The original allocated List records are a memory leak, and the free calls are indeed trying to free memory that was not malloc'ed (or more exactly were malloc'ed in a single big block). 最初分配的List记录是内存泄漏,并且free调用确实试图释放未进行malloc(或更确切地说是在单个大块中进行malloc)的内存。

You want an array of pointers to pointers to hold your lists: 您想要一个指针数组来保存列表:

/* 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM