簡體   English   中英

在C中正確釋放內存的方法

[英]Correct way to free memory in C

所以我試圖理解C中的內存管理的整個概念,我得到了這個代碼:

int main(int argc, int *argv[]) {
  item *x = NULL;
  x = (item *) malloc (sizeof(item));

  ...

  free_item(&x);
}

void free_item(item **x) {
  free(*x);
  *x = NULL;
}

item是早期定義的結構。 我感到困惑的一點是free_item(&x); 因為當我寫free_item(x); 並將功能更改為:

void free_item(item *x) {
  free(x);
  x = NULL;
}

代碼似乎與前一個代碼的工作方式相同。

那么,有什么區別嗎? 如果沒有,是否有任何理由,為什么有人會將一個結構指針的地址發送給一個函數,從而釋放這個結構?

是。 首先,我認為修改過的函數中存在拼寫錯誤。 它應該是:

void free_item(item *x) {
  free(x);
  x = NULL;
}

現在,為了差異。 free調用將成功,因為它所期望的是在堆上動態分配的數據的“指向類型的指針”變量。

第二部分, x = NULL ,將無法按預期工作。 請記住,在C中,當將參數傳遞給函數時,我們總是按值傳遞,而不是通過引用傳遞。 您正在傳遞變量的副本 ,因此x = NULL只是將臨時自動分配的x副本設置為NULL ,而不是作為參數傳遞的實際變量。

您更改的原始功能正確地執行了這兩個部分。

  1. 在第一種情況下,要修改指針變量xcontent ,需要使用引用傳遞。 這就是為什么&x和雙指針被用來free()main()分配的記憶的原因。 這是對的。

  2. 在第二種情況下,將創建x的函數本地副本並將其傳遞給free_item() ,這對main()存在的x沒有影響。 x = NULL; 將僅在free_item()內部具有范圍。

在您的第一個示例中,您使用類型指針的參數調用free_item指向項目的指針(假設item **x參數)。

在第二個示例中,將點值( main::x )復制到free_item::x (不同的范圍),並將復制的值設置為NULL (之后丟棄值)。

添加printf("%p\\n", x); main()的末尾(在free_item之后)。

在第一個示例中,您將看到NULL ,第二個x仍將設置為先前存儲在那里的地址。

在第一個例子中,假設您的指針位於地址0x00400000 ,它指向分配在0x00410000內存。

0x00400000 0x00410000 <- x is stored here
0x00400004 0x00400000 <- tmp described later; point to x
...
0x00410000 .......... <- x points here; start of item - returned by malloc

當您調用item **tmp = &x您將看到它將包含地址0x00400000 (並且tmp本身將存儲在不同的內存地址上)。

然后在free_item()

free(*tmp);     // The same as free(0x00410000)
*tmp = NULL;    // Modifies data at 0x00400000 = NULL

使用free時,傳遞指針,而不是指針的值。

所以,如果你使用

 item *x

,你應該使用

free(x)
  1. x = (item *) malloc (sizeof(item)); 沒必要。 x = malloc(sizeof(item)); 就足夠了。

2。

void free_item(item *data){
  free(data);
}

這是正確的方法。

  1. 編寫慣用的C代碼。 沒有區別,但很難進行調試和維護。

我會寫free_item(x); 而不是free_item(&x)並且有free_item(item **x)

暫無
暫無

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

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