0

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

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

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

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

我正在实现的链表函数似乎在工作 except destroyList(),它释放了传递给函数的节点的所有分配内存以及所有后续节点。

这是实现:

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

4 回答 4

1

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

于 2013-10-02T15:18:07.850 回答
1

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

于 2013-10-02T16:36:01.970 回答
0

只有具有malloc(或类似)的东西才需要free.

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

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

然后你会像这样分配:

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

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

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

于 2013-10-02T15:14:59.937 回答
0

您可能超出了堆栈。

尝试这个:

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

当然,也可能是您传入了错误的 pNode,在这种情况下,这将无法解决。

或者您在其他地方损坏了堆。

于 2013-10-02T15:16:49.460 回答