2016-03-09 32 views
2

我注意到,這個工作正常,但我不會期望它:C:做-而自由鏈表

do { 
    free(params); 
    } while ((params = params->next)); 

通常我會用這樣的事情,但不爲看優雅:

do { 
    params_t *next = params->next; 
    free(params); 
    params = next; 
    } while (params); 

(代碼意味着params分配)

或者:

while (params) { 
    params_t *next = params->next; 
    free(params); 
    params = next; 
    } 

可能無關,但我使用-std=gnu11clang

第一段代碼是否有效?

+3

不,這是不確定的行爲,並不能保證工作。 –

+0

你是如何獲得名單的頭?我在處理鏈表時學到的東西是一個包含N個節點的列表具有N-1個鏈接。當你知道的時候顯然是神祕的,當你不知道時通常是致命的。將打印語句添加到所有三個循環的主體中,並對節點和鏈接進行物理計數。 –

回答

3

你的第一個版本不正確,在調用free()之後,它的未定義行爲依賴於內存的內容。它可能會發生作用,但這只是未定義的行爲,發生在做出似乎定義明確的事情上。它確實不是。

你當然也可以只使用正確的循環結構,並有更好的生活:

for (params_t *next; params != NULL; params = next) 
{ 
    next = params->next; 
    free(params); 
} 

這似乎是比其他的替代品更好的匹配,因爲你可以使用for結構的各種條款用地。它仍然是一個雙線程,但也有太簡潔的代碼。 :)

+0

大部分時間使用'for'都很好。 – deepmax

2

這段代碼

do { 
    free(params); 
    } while ((params = params->next)); 

是未定義行爲,因爲是訪問的對象是沒有生命的嘗試。

此代碼段

do { 
    params_t *next = params->next; 
    free(params); 
    params = next; 
    } while (params); 

也是錯誤的(假設沒有檢查該params爲等於NULL循環之前),因爲在一般params最初可以等於NULL。第一個代碼片段存在同樣的問題。

只有這段代碼

while (params) { 
    params_t *next = params->next; 
    free(params); 
    params = next; 
    } 

是有效的。:)