[英]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
,而不是作為參數傳遞的實際變量。
您更改的原始功能正確地執行了這兩個部分。
在第一種情況下,要修改指針變量x
的content
,需要使用引用傳遞。 這就是為什么&x
和雙指針被用來free()
從main()
分配的記憶的原因。 這是對的。
在第二種情況下,將創建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)
x = (item *) malloc (sizeof(item));
沒必要。 x = malloc(sizeof(item));
就足夠了。 2。
void free_item(item *data){
free(data);
}
這是正確的方法。
我會寫free_item(x);
而不是free_item(&x)
並且有free_item(item **x)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.