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

试图释放()链表节点会导致C中的分段错误,c,pointers,linked-list,segmentation-fault,C,Pointers,Linked List,Segmentation Fault,我想我的问题很简单。是的,我知道关于堆栈溢出有几个链表/分段错误相关的问题,但我认为这些问题与未初始化的指针有关,而我认为我的问题与字符串有关 我有一个链表,它的节点结构由两个变量组成:一个指向下一个节点的链接和(!)一个字符串 我的问题:如何通过free()ing字符串来释放节点的内存(记住它是mallocated的),而不会导致分段错误 浏览与free()和strings相关的其他问题时,我的印象是没有必要free()它们。但是如何释放一个内部有嵌套字符串的struct 我正在实现的链表函数

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

我有一个链表,它的节点结构由两个变量组成:一个指向
下一个
节点的链接和(!)一个
字符串

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

浏览与
free()
strings
相关的其他问题时,我的印象是没有必要
free()
它们。但是如何释放一个内部有嵌套字符串的
struct

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

以下是实现方法:

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;
};

只有具有
malloc
(或类似)的东西才需要
免费的

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

struct listNode{
    char *addr;
    struct listNode *next;
};
struct ListNode Node = malloc(sizeof(struct listNode));
Node.addr = malloc(size of the string);
然后你会这样分配:

struct listNode{
    char *addr;
    struct listNode *next;
};
struct ListNode Node = malloc(sizeof(struct listNode));
Node.addr = malloc(size of the string);
您必须先释放字符串,然后再释放节点本身。字符串作为结构的一部分,具有固定长度,因此没有可释放的字符串


然而,你的问题肯定是别的。尽量避免递归(即,您的示例使用递归-在一个大列表上,这将导致堆栈溢出),并在释放指针时将其置零,并在使用指针之前检查指针(非null)。

您可能会超出堆栈

试试这个:

void destroyList(struct listNode *pNode){
    while (pNode) {
        struct listNode *x = pNode;
        pNode = pNode->next;
        free(x);
    }
}
当然,可能是您传入了一个错误的pNode,在这种情况下,这无法修复


或者您已损坏了其他位置的堆。

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

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

我想我应该澄清一下:调用
free()吗
在由
malloc
返回的结构上,如果该结构包含字符串,则尝试释放其中的字符串会导致分段错误?否。
free
不知道或不关心它正在释放的内存块的内容。好的,非常感谢所有建议。节点的分配与代码中的其他地方完全相同。看来我将不得不继续在别处调试。至于递归,这是项目的一个要求@AndrewMedico感谢您的回答/评论。现在我真正了解了更多关于C中内存分配的本质。从Java来到C,这是一个陌生的领域。如果列表太大,那么递归将是不可能的——除了放弃它进行循环之外,没有其他方法!这个程序有一个命令行arg,它决定了这个循环的次数…我目前使用的是10,所以这不应该是一个问题,但我知道这可能会导致问题。好的,谢谢!这意味着问题一定在我的代码中的其他地方。我收到的错误消息只是“分段错误”,因此我正在尝试缩小可能的原因。是否可能在某个点向节点中写入的字符数超过了MAX_ADDR_长度?可能是错误的,但这可能会弄乱指针。另外,您是否在创建时在null旁边初始化?在这方面,请参见calloc。。