簡體   English   中英

C malloc錯誤釋放結構

[英]C malloc error freeing struct

我剛剛重新開始學習C,但是我確實對一些內存管理細節感到困惑。 我越來越

沒有分配要釋放的指針...中止陷阱

用於以下代碼。 真的需要每個malloc免費嗎? 為什么我的代碼是錯誤的?
謝謝!

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

你做 :

cells[i] = *newList(N);

它將單元cells中的每個元素設置為由newList動態分配的列表的副本。 因此, newList動態分配一個列表,然后使用指向該動態分配的List的指針,對其進行取消引用,然后將其復制到cells[i] 因此,稍后在您使用free()每個元素時:

free(&cells[i]);

這是行不通的,因為cells[i]中的每個元素都是一個List ,而不是malloc()分配的List * (列表指針malloc()

因此,您有兩個選擇。 一個(不好的)方法是刪除最后一個free()行,因為沒有什么要釋放的。 但是,這掩蓋了一個更大的問題,即您現在有內存泄漏,因為您無法返回並釋放由newList()創建的動態分配的List

相反,您可能希望擁有一個指向列表的指針數組,可以通過將其更改為:

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

因此cells[i]引用List * newList()返回這樣的指針,因此您可以將該行更改為:

cells[i] = newList(N);

同樣, addList()采用這樣的指針,因此您只需將該行更改為:

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

因為&cells[i]會將指針的地址傳遞給它,這不是您想要的。

最后,將free語句更改為:

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

問題是您要分配一個列表數組,將列表的全部內容復制到數組元素中,然后嘗試釋放它們。 最初分配的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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM