2013-10-21 67 views
0

所以這裏是我的代碼銷燬鏈表。銷燬C中的鏈接列表

void destroy(node *h){ 
    if (h->next!=NULL){ 
     destroy(h->next); 
    } 
    free(h); 
    h=NULL; 

} 

的問題是,打印輸出還是一串數字:

11,2,15,3,9,//之前銷燬

28495936,28495968,28496064,28496096 ,0,//銷燬後

不幸的是,由於分配原因,我無法更改void destroy(node *h)參數。 我試過使用while循環方法,但我仍然得到相同的結果。我也嘗試轉移到左側,並從結尾刪除,但我不能刪除最後一個節點。

在此先感謝。

--edit --- 的要求,這裏是打印功能

void print(node* N){ 
     printf("%d, ", N->value); 
    if (N->next) 
     print_set(N->next); 
    if (N == NULL) 
     printf("Empty Set"); 
} 
+1

我們可以看到您用來打印列表的代碼嗎? – Kaidjin

+0

你爲什麼要打印你銷燬的清單?如果賦值是'void destroy(node *)'的原型,那麼你不能在調用'destroy()'的函數中改變指針,所以你將不能使指針變爲空以防止打印。 – Eregrith

+0

我已經添加了我的打印代碼。 – User49230

回答

1

這裏的問題是h=null在你的函數中沒有任何作用。您正在修改本地參數,因此它不會在函數外發生任何影響。

因此,你所做的唯一事情就是釋放內存,但你保持地址相同。您的列表仍然存在,指向隨機內存位置(不是隨機的:與以前相同,但是此內存位置的值是隨機的)

當您在此之後列出您的列表(這很奇怪,因爲您應該摧毀它...爲什麼你想要再次打印它?),你在內存中打印隨機值。

這是一個問題,因爲您的程序也可能會崩潰(您正在訪問未分配的內存)。

的解決方案,不幸的是,需要改變你的函數的簽名:

void destroy(node **h){ 
    if ((*h)->next!=NULL){ 
     destroy((*h)->next); 
    } 
    free(*h); 
    *h=NULL; 

} 

如果你不能,你必須摧毀它,這樣的後置指針爲NULL:

void destroy(node *h){ 
    if (h->next!=NULL){ 
     destroy(h->next); 
     h->next=NULL; 
    } 
    free(h); 
} 

,並在調用函數:

destroy(myList); 
myList=NULL; 
+0

工作。我不確定我可以在我的主要方法中設置myList = NULL這就是問題所在。 – User49230

+0

我沒有看到任何其他的方式來確保你不使用被銷燬的列表。由於內存被釋放,保持指針沒用,並且沒有設置爲NULL,所以可以使用它再次在代碼中,這會導致你的應用程序崩潰(或者類似於你在這個問題中詢問的行爲) – Kaidjin

+0

在給定情況下,似乎沒有其他辦法了,我會問我的講師。幫助!:) – User49230

2

您必須設置h->next = NULL。另外,在致電destroy之後,請確保您不再使用指針,因爲它已被釋放。所以,總是在destroy(n)之後,確保你有n = NULL

一個更好的辦法可能是簽名更改爲void destroy(node **h),所以代碼變成:

void destroy(node **h){ 
    if ((*h)->next!=NULL){ 
     destroy(&h->next); 
    } 
    free(*h); 
    *h=NULL; 
} 

然後,你可以確保你沒有使用指針之後。

在你print功能,你必須在開始添加此檢查:

if(N == NULL) return; 
+0

肯定有幫助,但是當我打印時,我得到一個數字打印: '11,2,15,3,9, //之後 11886656,' – User49230

+2

@ PatrickBuhagiar:那是因爲你的'print'函數包含一個錯誤。您必須在開始時檢查「NULL」(因爲它是「NULL」,因此無效)。我延長了我的回答。 – Albert

+0

@PatrickBuhagiar:你在哪個平臺上,使用哪個編譯器? – alk

0

我不知道你的結構是什麼樣子,但我猜是這樣的:

struct { 
    int something; 
    int* value; 
    list* next; 
} 

問題是,即使h是空指針,h->valueh->next都不是。它們是指向NULL+1NULL+2的指針,它們可能指向內存中的隨機地點。

+0

我的結構由一個int值和一個下一個指針組成。我應該怎麼做呢?我的意思是,我不能將h->值設置爲NULL .. – User49230

1

問題可能出現在您尚未發佈的代碼中!

我假設你保持一個'頭'指針到你的列表,你的代碼看起來像這樣。

Node * myList; 

.. do stuff.. 

destroy(myList); 
print(myList); 

問題是你沒有在銷燬後設置myList = NULL

destroy(myList); 
myList = NULL; 
print(myList); 

你的,因爲它修改本地參數h=NULLdestroy()沒有做任何事情。

+0

我不確定我可以在主方法中將myList設置爲null ... – User49230

+0

在這種情況下,您需要傳遞一個*指針* to myList - 請參閱@ Albert的解決方案(包括修復print()'。還要注意遞歸不是遍歷列表的推薦方法! – Roddy

0

試試這個代碼,如果u是單獨工作開左簽署名單

void destroy(node *h){  
    node *n;  
    node *p; \\ variable to store previous term 
    n=h; 
    while(n->next!=NULL){ 
    p = n; 
} 
    p->next=NULL; 
    free(n); 

}

+0

這段代碼是del一次只列出一個期限(最後一期)。 – Ashish

2

如果solution provided通過Albert是不可能的,因爲一些規則,您筆者在調查排放源的已經是唯一的可能記住名單的節點已被釋放,因此包含對內存的無效引用,並且因爲後者而編寫的代碼可能不會取消引用此類指針,也就是說它們可能不會傳遞給打印功能因爲這會通過訪問un/deallocated內存而引發未定義的行爲。

如果編寫這樣的潛在不安全代碼,作爲作者的責任是謹慎使用它,並且在離開項目後爲您的程序員維護代碼做好記錄。