2014-10-07 210 views
1

我試圖運行此程序,其中創建了一個字符數組並動態分配了內存。之後,數組元素將填充10個連續位置的字符串「hello」。使用strdup()函數調用將值分配給字符串元素。在while循環中釋放()

一旦分配了所有元素,元素就會在while循環中釋放。當我在Visual Studio中運行程序時,在最後一個指向char數組的指針被釋放後,程序崩潰。我相信while循環的終止條件是正確的。但是我無法確定究竟是什麼導致了這個問題。

代碼:

char **p; 
int i; 

p = malloc(10 * sizeof(char *)); 
for (i = 0; i < 10; i++) { 
    p[i] = strdup(「hello」); 
} 

while (*p) { 
free(*p++); 
} 
+2

'* p'是類型指針,不會被評估爲* false *,除非它是'NULL'。當你超出數組「p」的範圍時,'* p'不會神奇地評估爲NULL。然而,你可以通過自己採取額外的措施來使其工作,即'p = malloc(11 * sizeof * p); p [10] = NULL;/*其餘部分與你的一樣* /' – ThoAppelsin 2014-10-07 06:44:38

回答

4

如果您非常想使用while循環,那麼你應該寫的代碼如下方式

char **p; 
int i; 

p = malloc(11 * sizeof(char *)); 
for (i = 0; i < 10; i++) { 
    p[i] = strdup(「hello」); 
} 

p[i] = NULL; 

while (*p) { 
free(*p++); 
} 

考慮到,你也需要遊離對自身的初始值帳戶。因此,帶有while循環的正確代碼可能看起來像

char **p; 
int i; 

p = malloc(11 * sizeof(char *)); 
for (i = 0; i < 10; i++) { 
    p[i] = strdup(「hello」); 
} 

p[i] = NULL; 

char **q = p; 

while (*q) { 
free(*q++); 
} 

free(p); 
+0

準確地說:釋放循環期望指針數組中的_sentinel_,原始分配循環從不寫入。你的p [i] = NULL語句寫入哨兵。 – 2014-10-07 06:50:28

+0

不應該'q'被聲明爲'char **'而不是'int **'嗎?我知道指針是一樣的,但爲了一致性... – xOneca 2015-01-04 17:22:23

+0

@xOneca謝謝,這是一個錯字。:) – 2015-01-04 17:33:26

1

你應該遍歷十個元素,直到不存在sentinel valueNULL):

for (i = 0; i < 10; i++) { 
    free(p[i]); 
} 

您當前的代碼取消引用p[10],這是陣列外範圍並因此觸發undefined behaviour

1

訪問數組綁定外的值意味着未授權的內存訪問。僅限於此,由於p++,您最終崩潰。所以試試這個。

i=0; 
    while(i<10) 
    { 
    free(p[i]); 
    i++; 
    }