尝试释放()链表节点导致C中的分段错误

时间:2013-10-02 15:13:11

标签: c pointers linked-list segmentation-fault

现在秋季学期已经开始,像我这样的人来到这里寻求计算机科学家庭作业的帮助就不足为奇了。

我认为我的问题很简单。是的,我知道堆栈溢出有几个链表/分段故障相关的问题,但我认为这些与未初始化的指针有关,而我认为我的问题与字符串有关。

我有一个链表,其节点结构包含两个变量:指向next节点的链接和(!)a string

我的问题:如何通过malloc字符串释放节点的内存(请记住它是free())而不会导致分段错误?

在浏览与free()strings相关的其他问题时,我的印象是没有必要free()他们。但是如何释放其中包含struct嵌套字符串的string

我负责实现的链表函数似乎正在使用destroyList(),但其规范只是为了释放传递给函数的节点的所有已分配内存以及所有后续节点。 / p>

这是实施:

void destroyList(struct listNode *pNode){
    if(pNode->next != null){
        destroyList(pNode->next);
    }
    free(pNode);
}

这里是listNode结构:

struct listNode{
    char addr[MAX_ADDR_LENGTH];
    struct listNode *next;
};

4 个答案:

答案 0 :(得分:1)

您的“字符串”(char缓冲区)是列表节点结构的一部分。它不会与节点分开分配,因此不需要释放它。只需释放节点就可以了。

答案 1 :(得分:1)

使用malloc()时经验法则是free()。字符串不需要是free(),因为free()节点释放分配给整个结构的内存,包括字符串的内存。而且,为什么不使用gdb或valgrind来调试故障的确切位置?在gdb中,您可以使用where和print stacktrace等选项来精确定位段错误的位置。现在学习gdb是一项很好的投资。这部分代码对我来说很好。

答案 2 :(得分:0)

只有malloc(或类似)的内容才需要free

例如,如果你的结构是这样的:

struct listNode{
    char *addr;
    struct listNode *next;
};

然后你会像这样分配:

struct ListNode Node = malloc(sizeof(struct listNode));
Node.addr = malloc(size of the string);

然后你必须释放字符串然后释放节点本身。您的字符串作为结构的一部分,具有固定的长度,因此没有可用的字符串。

但是,您的问题必须是其他问题。尽量避免递归(即你的例子使用递归 - 在一个大的列表上这会导致堆栈溢出)并在释放它们时使你的指针无效,并在使用之前检查指针(非空)。

答案 3 :(得分:0)

你可能会超越筹码。

试试这个:

void destroyList(struct listNode *pNode){
    while (pNode) {
        struct listNode *x = pNode;
        pNode = pNode->next;
        free(x);
    }
}

当然可能是你传入一个糟糕的pNode,在这种情况下这不会修复。

或者你已经在其他地方破坏了堆。