c - 在链表中附加一个节点 - 为什么分段错误?
问题描述
我正在 C 中实现一个具有结构的链表
struct node
{
int data;
struct node *next;
};
我已经编写了 append 函数来在链表的末尾添加一个节点,如下所示,以及 display 函数来显示所有节点。但是由于我认为附加功能的一些不一致,显示会出现分段错误。这里有什么问题?我的书确实有类似的附加功能,使用 malloc。我想知道我的功能出了什么问题。
void append(struct node **q, int d)
{
struct node *temp;
temp = *q;
printf("\nBegin: Address at temp = %u", temp);
while (temp!= NULL){
temp = temp->next;
printf("\nTravel: Address at temp = %u", temp);
}
struct node p1;
p1.data = d;
p1.next = NULL;
*q=&p1;
printf("\nEnd: Address at *q = %u\n", *q);
printf("\n*q->data = %d next = %u", (*q)->data,(*q)->next );
}
void display(struct node *q)
{
printf("\n");
while (q != NULL){
printf(" -> %d",q->data);
q = q->next;
}
}
int main(int argc, char *argv[])
{
struct node *p;
p = NULL; /* empty linked list */
printf("\nNo. of elements in the Linked List = %d", count(p));
append(&p,1);
display(p);
append(&p,2);
display(p);
printf("\nNo. of elements in the Linked List = %d", count(p));
}
输出:
No. of elements in the Linked List = 0
Begin: Address at temp = 0
End: Address at *q = 6684096
*q->data = 1 next = 0
-> 1Segmentation fault
但是,当我更换
struct node p1;
p1.data = d;
p1.next = NULL;
*q=&p1;
和
temp = *q;
*q = malloc(sizeof(struct node))
temp->data = d;
temp->next = NULL;
错误消失了。
有人可以解释原因吗?
解决方案
在这里,您使用局部变量的地址,使其在离开函数后可访问:
*q=&p1;
然后你离开这个功能。
每当稍后访问它时,它将访问不再是局部变量的内存。
您需要为变量分配内存。为此使用malloc()
。
例如:
struct node *p1;
p1 = malloc(sizeof(*p1));
/* skipping recommended check of success/NULL */
p1->data = d;
p1->next = NULL;
*q=p1;
还有更多问题,例如您让列表以新节点开头,然后是 NULL,这会丢失/泄漏您以前的所有列表。但是最直接的问题是在一个过去的局部变量存在之后引用它的内存位置引起的。
推荐阅读
- javascript - React Native:功能组件中的getter函数?
- excel - 如何在下拉列表中将工作表(工作表)设置为同名
- haskell - 在 Haskell 中重新创建解析器函数“many”的问题
- javascript - npm install react-navigation-stack@^1.10.3 给出错误
- python - FastAPI/Pydantic 可以单独验证列表中的输入项吗?
- python-3.x - /NewListing 处的 NoReverseMatch
- python - minsize() 和 maxsize() 方法在 tkinter python(Toplevel) 中不起作用
- ssh - 是否可以将 url(使用 IP)重定向到另一个 url(其他 IP)?
- python - 如何在 statsmodels 中使用 gamma GLM 的尺度和形状参数
- java - 将 JarSigner 与 RSASSA-PSS 一起使用