我对c(和这个网站)相当新,我遇到了很多关于分段错误的问题。我正在编写一个程序,它创建一个数字链接列表并按升序插入值。
void insert(struct element **head, struct element *new){
if((*head)->next == NULL && (*new).i > (*(*head)->next).i){
(*head)->next = new;
return;
}
if((*head)->next == NULL && (*new).i < (*(*head)->next).i){
new->next = (*head)->next;
*head = new;
return;
}
struct element *prev = *head;
struct element *current = (*head)->next;
while(current->next != NULL){
if((*new).i < (*current).i){
prev = current;
current = current->next;
} else if((*new).i > (*current).i){
new->next = current;
prev->next = new;
}
}
}
int main (void){
struct element **head;
int value;
printf("%s", "TEST" );
printf("%s" , "Please type in an integer value. ");
scanf("%d" , &value);
printf("%s", "TEST" );
do{
printf("%s", "TEST" );
struct element *new;
if((new = malloc(sizeof(struct element))) == NULL){
return(NULL);
}
printf("%s", "TEST" );
(*new).i = value;
printf("%s", "TEST" );
if(head == NULL){
*head = new;
printList(*head);
} else if(value <= 0){
printListBackwards(*head);
}
else {
insert(head, new);
printList(*head);
}
} while(value > 0);
关于插入或任何东西的逻辑是否正确,我都不需要帮助。我甚至没有机会真正测试它,因为我在提示后输入一个整数后立即出现分段错误。我知道它似乎很时髦,但规范要求你使用指向结构指针的指针(链表的头部)。
答案 0 :(得分:2)
您确定要成为element**
而不是element*
吗?这种额外的分离程度会给你带来麻烦,其中最重要的是难以阅读的代码。
这是跳出来的主要内容:
if(head == NULL){
*head = new;
printList(*head);
}
您确认head是一个NULL指针,然后立即尝试使用*
取消引用它。如果你真的坚持将head作为双指针,那么你需要在解除引用之前动态分配它。像这样:
if(head == NULL){
head = malloc(sizeof(element*));
*head = new;
printList(*head);
}
实际上可能在语法上并不完美(我来自C ++),但你明白了。说到C ++,在C中命名变量“new”通常被认为是不好的做法,因为new
是C ++中的关键字。
答案 1 :(得分:0)
在帖子的第二行引起了一个段错误
if((*head)->next == NULL && (*new).i > (*(*head)->next).i){
(*head)->next = new;
return;
}
分段错误意味着您正在尝试访问不允许的内存。例如,您不能取消引用NULL指针。
您的if
语句的评估方式如下。
检查(*head)->next
是否为空。
如果它不是NULL,则跳过其余部分。
如果它为空,那么您可以用(*head)->next
替换每个NULL
。这意味着以下部分&& (*new).i > (*(*head)->next.i)
可以重写如下&& (*new).i > ((*NULL).i)
...
简而言之,您正尝试取消引用NULL指针值。
请参阅@Parker Kemp的帖子。有很多次你正确地检查NULL但误解了它的含义。
我可以为你重写代码,但我认为通过像this one或this one这样的教程可以获得更多好处
我强烈建议您绘制数据结构图并绘制指针箭头。
答案 2 :(得分:0)
struct element **head;
你不想那样。取而代之的是,
struct element *head = NULL;
然后,当您调用insert时,请使用
insert(&head, new);
您还有许多其他错误和不良用法,但这是您特定问题的开始。