2013-04-23 79 views
0

這裏是我的流行代碼:)無法在我的彈出功能中釋放/釋放空間?

int pop (struct_of_ints *head_node){ 
int val; 
if (head_node == NULL){ 
    fprintf(stderr, "Empty stack.\n"); 
    return -1; 
} 
else { 
    struct_of_ints *curr; 
    struct_of_ints *prev; 
    curr = head_node; 
    prev = NULL; 

     while (curr->next != NULL) { 
      prev = curr; 
      curr = curr->next; 
     } 

     val = curr->value; 

     if (prev == NULL) 
      head_node = NULL; 
    else 
      prev->next = curr->next; 
     free(curr) 
     return val; 


} 

} 

當我嘗試釋放(CURR),但是,我得到一個分段錯誤,當我跑Valgrind的,我得到「無效免費(信息/刪除/刪除[]「,」地址0x51c1f60在一個大小爲32的塊中是16個字節「以及」大小爲8的無效讀取「......我不知道有什麼問題。如果有人能幫助我會很感激。謝謝!

+0

我建議你使用雙鏈表來代替尾指針。如果你想從尾部移除,會使生活變得更簡單。或者,如果你實現了一個堆棧,只需在頭上按/彈出即可。 – 2013-04-23 03:05:37

+0

用'-g'標誌編譯代碼,運行'gdb'來檢查你的錯誤。 – MYMNeo 2013-04-23 03:09:22

回答

3

您正在將指針* head_node傳遞給函數,該函數正在通過值傳遞。要更新* head_node,嘗試通過** head_node,並更改代碼::

int pop (struct_of_ints **head_node) 
{ 
    int val; 
    if (*head_node == NULL) 
    { 
     fprintf(stderr, "Empty stack.\n"); 
     return -1; 
    } 
    else 
    { 
     struct_of_ints *curr; 
     struct_of_ints *prev; 
     curr = *head_node; 
     prev = NULL; 
     while (curr->next != NULL) 
     { 
      prev = curr; 
      curr = curr->next; 
     } 

     val = curr->value; 

     if (prev == NULL) 
      *head_node = NULL; 
     else 
      prev->next = curr->next; 
     free(curr) 
     return val; 
    } 
} 
2

我的猜測是,出現這種情況,你突然出現的所有節點只後,再嘗試彈出一個。這是因爲你在函數內的賦值爲head_node不會傳播到調用該函數的代碼。 head_node是函數內部的局部變量,您需要將它作爲參考傳遞(即作爲指向指針的指針)。

當最後一個節點被彈出時會發生什麼,是函數釋放它,但調用它的代碼仍然會有指針。所以下一次調用將會有一個指向free'd內存的指針,當訪問該指針時將導致未定義的行爲。未定義的行爲通常會導致崩潰。