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 个字节”之类的消息free'd”和“无效读取大小 8”...我不知道出了什么问题。如果有人可以提供帮助,我将不胜感激。谢谢!

4

2 回答 2

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;
    }
}
于 2013-04-23T03:11:48.590 回答
2

我的猜测是,这只有在你弹出所有节点之后才会发生,然后再尝试弹出一个。这是因为您对函数内部的分配head_node不会传播到调用该函数的代码。head_node是函数内部的局部变量,您需要将其作为引用传递(即作为指向指针的指针)。

弹出最后一个节点时会发生什么,函数是空闲的,但调用它的代码仍然有指针。因此,下一次调用将使用指向已释放内存的指针,这将在访问该指针时导致未定义的行为。未定义的行为通常会导致崩溃。

于 2013-04-23T03:12:13.173 回答