2015-10-11 46 views
2

我真的很困惑這個二維字符數組如何正確釋放字符**用C

char **arg = malloc(sizeof(char*) * argc) 
for (int i = 0; i < argc; i++) 
    arg[i] = malloc(sizeof(char) * size) 
... 
... 

現在假設經過一系列的操作,我忘了變量的argc,我怎麼能釋放那些記憶? 我可以做這樣的事嗎?在所有情況下,這絕對正確嗎?

char **tmp = arg; 
while (*tmp != NULL){ 
    free(*tmp); 
    tmp++; 
} 
free(arg); 
+0

數組不是NULL,只對字符串有效(char *在C中) – John

+0

實際上爲char *數組分配內存,然後爲數組中的每個項分配內存。你必須先釋放物品然後釋放它自己的陣列。 – milevyo

+0

這實際上並不是一個壞主意,但你應該在數組的末尾明確地加上NULL。我在很多情況下都使用它,這很好。 –

回答

3

沒有

while(*tmp != NULL){ 

你可以達到零上,您將間接引用的內存還沒有被分配到並引發未定義行爲的一個點。

或如建議您可以明確地指定一個NULL到最後分配的指針,在這種情況下,它將工作。

+0

在這種情況下,釋放這些指針的正確方法是什麼? –

+1

@lplouis:跟蹤有多少指針分配給內存 –

+0

,所以argc一定不能被遺忘? –

-1

,如果你定義的char *數組是這樣的:

char **arg = calloc(1, sizeof(char *) * argc);

你可以確保每一個未定義的指針將等於NULL

,然後你可以使用while循環幾乎像你建議:

char *tmp = *arg; 
while (tmp != NULL) { 
    free(tmp); 
    tmp++; 
} 
free(arg); 
0

正如其他人所說的,如圖所示的循環中釋放的問題是一個額外的項目(argc + 1)需要被分配並且它必須被設置爲NULL。另一種技術是第一分配空間的指針,你已經做了

char **arg = malloc(sizeof(char*) * argc) 

然後,如果你知道所有的後續項目的大小相同,在一個巨大的塊分配,並設置其餘元素在間隔的偏移

arg[0] = malloc(sizeof(char) * size * argc); 
for (int i = 1; i < argc; ++i) 
    arg[i] = arg[i - 1] + size; 

從而釋放空間是不費吹灰之力:沒必要還記得ARGC

free(arg[0]); /* this will free the memory used by all the elements */ 
free(arg); 

大缺點這種方法是,如果任何的數組元素溢出,它會破壞下一個項目。除非它是最後一個項目,否則這不能通過堆檢查輕鬆檢測到。