2017-05-28 62 views
1

我正在使用搜索樹,並查看樹是否結束我檢查它是否爲空。 我的問題是當我使用免費()指針值不成爲NULL打印功能不正確讀取釋放值

我也嘗試使用指向空閒的指針,然後設置爲NULL,但它沒有工作。

在這種情況下,我想刪除搜索樹上的最大數字,但我的打印函數不識別釋放的值並打印0。

typedef struct nodo { 
    int val; 
    struct nodo *l, *r; 
} *ABin; 

void print (ABin a) { 
    if (a != NULL) { 
     print (a -> l); 
     printf(" %d ",a -> val); 
     print (a -> r); 
    } 
} 

ABin remBiggerA (ABin *a) { 
    ABin b = (*a), aux = b; 
    int i = 0; 
    if (b == NULL) i = 1; 
    while (i == 0) { 
     if (b -> r == NULL) { 
      free (b); 
      i = 1; 
     } 
     else b = b -> r; 
    } 
    (*a) = aux; 
    return aux; 
} 
+2

「typedef」指針通常是個壞主意。 –

+0

我已經給出了最好的答案,我可以提供所提供的信息,但是如果您將釋放的指針設置爲null,並且您的空白檢查仍未註冊,那麼您遇到了完全不同的(幾乎肯定是基於邏輯的)問題。是否可以發佈一個最小可驗證的例子? –

回答

4

在指針上調用free()後,它不會將指針設置爲空,它將使其無效。這意味着進一步訪問該指針地址會導致未定義的行爲。您無法訪問或打印已釋放內存的信息。然而,你可以釋放一個指針,然後立即將它設置爲null - 這是一個非常有效的事情。如果你已經這樣做了,仍然有問題,那麼我懷疑你的問題在別的地方。

2

這是預期的行爲。您可以在The GNU C Library上找到有關free()功能的文檔。

釋放塊會改變塊的內容。在釋放它之後,不要期望在塊中找到任何數據(例如指向塊鏈中下一個塊的指針)。

正如Hiko提到的,在調用free()之後,將指針指定爲NULL是一種好習慣。

所以,

free (b); 
b = NULL; 

將解決你的問題。


編輯:正如意見建議@Seb,還要檢查The POSIX manual for free()

+2

我建議人們引用POSIX(opengroup)手冊,而不是GNU手冊;前者往往更加準確和標準兼容,不太重視*擴展*。 [POSIX的'free'手冊可以在這裏找到](http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html)。儘管如此,將OP指向手冊是一個好主意! – Sebivor

+0

也許你應該添加你在glibc文檔中添加的手動鏈接中的「任何指針的使用」文本,以防將來頁面移動。 –