我看到一些类似的话题,但他们没有帮助我。我制作了链表,以及插入元素的功能。
struct node{
int data;
struct node* next;
} node;
struct node* head;
void insert(struct node* head,int x);
int main(){
struct node* head = (struct node*) malloc(sizeof(struct node));
int x;
while(1){
printf("Please enter numbern");
scanf("%i", &x);
insert(head,x);
print(head); // function that works
}
return 0;
}
void insert(struct node* head,int x){
struct node* temp = malloc(sizeof(struct node));
temp->data = x;
temp->next = NULL;
if(head->next != NULL) temp->next = head;
head = temp;
free(temp);
}
GDB 说我在 if 构造的行上遇到分段错误:
if(head->next != NULL) temp->next = head;
我的错误在哪里?
是的,它当然会给出分段错误。if
情况下,您正在访问head->next
. head
只是类型 struct node
的指针。首先分配内存空间,然后访问字段。现在您正在访问内存中的一些不适当的地址(head->next)
内核会给进程带来"分段错误"。例如,做struct node* head = malloc(sizeof(struct node));
然后可以访问head->next
。
在调用 if(head->next != NULL) temp->next = head;
之前,您需要检查head
。 头可能包含空。因此,请在if(head->next != NULL) temp->next = head;
之前添加if(head != NULL)
编辑:如果您在提问时发布了完整的代码,则很容易以适当的方式为您提供帮助。现在人们认为我们回答错了,他们投了票。好吧,无论如何,这是我的答案。您不应该在插入函数中自行调用free(temp);
。因为您将print
功能中访问该内存。您正在自行释放分配insert()
内存,并尝试在打印功能中访问。这导致了分段错误。从插入功能中删除free(temp);
。
请注意,您声明的是两个名称相同(head)但作用域不同的变量:
struct node* head;
void insert(struct node* head,int x);
int main()
{
struct node* head = (struct node*) malloc(sizeof(struct node));
在插入函数中,在检查"head"是否为NULL之前取消引用"head"。 始终检查空值,永远不要假设任何事情。在函数结束时,您释放新创建的节点,这也是错误的。最后,插入函数的参数不正确,您需要传递指针的地址才能更改头部指向的内容。
该函数应如下所示
void insert(struct node** head,int x)
{
struct node* temp = malloc(sizeof(struct node));
temp->data = x;
temp->next = NULL;
assert( head != NULL ); // should always be an address
if ( *head == NULL )
{
*head = temp; // done, first in list
}
else // insert as first in list
{
tmp->next = *head;
*head = tmp;
}
}
然后你应该这样称呼它:
insert(&head,x);