我已经在C语言中编写了一个非常简单的链表节点结构,其中包含一些通用指针数据和指向下一个节点结构的指针。我有一个函数将会取得一个链表节点,并将其与任何其他链接的节点一起删除。目前,这个函数的实现方式如下:
void freeLinkedList(LinkedListNode *node)
{
LinkedListNode *currentNode = node;
LinkedListNode *previousNode = NULL;
do
{
free(currentNode->data);
previousNode = currentNode;
currentNode = currentNode->next;
printf("Freeing node... %s\n", previousNode->name);
free(previousNode);
printf("freed it!\n");
} while (currentNode != NULL);
printf("Deleted node and all referencing nodes!");
}
这个函数非常简单,它从给定的节点开始遍历,并继续删除指针数据,指向下一个节点(如果有),然后删除前一个节点的内存。这确实按照预期工作...但只在某些情况下。
实际的LinkedList结构看起来像这样:
typedef struct LinkedListNode {
void *data;
struct LinkedListNode *next;
char name[50];
} LinkedListNode;
在像这样动态分配的结构中,该函数可以完美地工作:
LinkedListNode *myNode1 = malloc(sizeof(struct LinkedListNode));
LinkedListNode *myNode2 = malloc(sizeof(struct LinkedListNode));
LinkedListNode *myNode3 = malloc(sizeof(struct LinkedListNode));
strcpy(myNode1->name, "Node1");
myNode1->data = NULL;
myNode1->next = myNode2;
strcpy(myNode2->name, "Node2");
myNode2->data = NULL;
myNode2->next = myNode3;
strcpy(myNode3->name, "Node3");
myNode3->data = NULL;
myNode3->next = NULL;
freeLinkedList(myNode1); // CALLING DELETE FUNCTION HERE
但是,如果我使用的函数所分配的结构体不是在堆内存上,而是在自动堆栈内存中,就像这样:
LinkedListNode myNode1 = {NULL, NULL, "Node1"};
LinkedListNode myNode2 = {NULL, NULL, "Node2"};
LinkedListNode myNode3 = {NULL, NULL, "Node3"};
myNode1.next = &myNode2;
myNode2.next = &myNode3;
freeLinkedList(&myNode1); // CALLING DELETE FUNCTION HERE
这个函数的这一行出现了SIGSEGV - 分段错误:
free(previousNode);
这个错误仅在最后一个节点的自由函数中发生,也就是说输出结果会显示:"Freeing node... node3,然后程序崩溃。
但有趣的是,到目前为止,我只在使用上面的示例时遇到过这个错误。如果我再声明一个本地LinkedListNode结构,像这样:
LinkedListNode myNode1 = {NULL, NULL, "Node1"};
LinkedListNode myNode2 = {NULL, NULL, "Node2"};
LinkedListNode myNode3 = {NULL, NULL, "Node3"};
LinkedListNode myNode4 = {NULL, NULL, "Node4"};
myNode1.next = &myNode2;
myNode2.next = &myNode3;
freeLinkedList(&myNode1);
这个函数实际上是有效的,而且按预期执行了所有操作。
我已经尝试了几个小时来思考这可能是为什么,但我只是停滞不前。这是否与我试图释放在堆栈上分配的内存有关?