我正在尝试用 C 实现一个链表。这是我对 Node 结构的定义,后面是一个将 Node 添加到链表末尾的函数。
struct Node{
char *name;
struct Node *next;
};
typedef struct Node Node;
void addNode(Node *head, char n[100]){
if(head->next == NULL){
Node new;
new.name = n;
new.next = NULL;
head->next = &new;
}
else{
addNode(head->next, n);
}
}
我可以创建一个头节点并将其指针传递给 addNode 函数,这样就可以将第二个节点添加到链表中。 (还值得一提的是,当我创建头节点时,我将其“next”指针设置为NULL以表示链表的末尾)问题似乎出在addNode函数的else分支中对addNode的递归调用,因为当我注释掉我的程序时,它不会崩溃。为什么这会导致我的程序崩溃?我该如何修复它?
最佳答案
if(head->next == NULL){
Node new;
new.name = n;
new.next = NULL;
head->next = &new;
}
你的问题其实就在这里。变量new
具有自动存储持续时间,这意味着它在声明它的 block 的末尾不再存在 - 在本例中,在右大括号处if()
的结尾。
您保存在 head->next
中的指针现在指向一个不再存在的对象 - 这称为“悬空指针”。当您稍后使用悬空指针时,程序的行为将不再定义。
您希望分配一个 Node
,该节点将在创建它的函数调用之外继续存在 - 这就是 malloc()
的用途:
if(head->next == NULL) {
Node *new = malloc(sizeof *new);
if (new) {
new->name = n;
new->next = NULL;
head->next = new;
} else {
/* malloc failed */
}
}
使用 malloc()
创建的对象的生命周期会延长,直到您将指向它的指针传递给 free()
,如果您要删除该对象,就会执行此操作。从链表中取出节点并将其丢弃。
关于C-尝试将节点添加到链表末尾会导致崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46313340/