2013-04-23 77 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内存的指针,当访问该指针时将导致未定义的行为。未定义的行为通常会导致崩溃。