我刚开始使用C,我认为整个指针/ malloc / free让我很生气。我试图定义一个简单的线性递归数据结构并循环遍历它,打印我循环的每个元素。 (代码如下)。
但是,当我尝试移动到下一个元素“插入”一个新元素时,我会收到Segmentation Fault:11
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct number_list {
int num;
struct number_list *next_num;
} numlist;
int main() {
numlist *cur, *pointer;
numlist *NewList=NULL;
cur = NewList;
cur = malloc(sizeof(numlist));
cur->num=5; // this operation is never reached too
cur = cur->next_num // Must I malloc?
printf("Reached."); // Is never reached.
cur->num=9;
pointer=NewList;
while (pointer!=NULL) {
printf("%d", pointer->num);
pointer=pointer->next_num;
}
return 0;
}
此外,我在另一个更大的程序中有一个while循环,其功能与此循环完全相同,除了在“填充”递归结构上。因此,我实际上不需要创建任何新元素,只需运行并打印出每个元素。但是,在循环打印最后一个元素的那一刻,它再次与Segmentation Fault:11崩溃。我猜这可能是因为我试图做pointer = pointer->next_num
。那么如何在C上正确地正确运行这样的数据结构?
答案 0 :(得分:1)
你有一些概念问题。首先,您需要知道指针与其指向的内存之间的区别;
int a1 = 0;
int a2 = 0;
int *b = &a1;
*b = 3;
// now a1 = 3, a2 = 0
b = &a2;
*b = 2;
// now a1 = 3, a2 = 2
这意味着在这两行中:
cur = NewList;
cur = malloc(sizeof(numlist));
第二个完全取代了第一个作业。
现在这一行:
cur = cur->next_num;
好next_num
尚未设置,因此cur设置为垃圾内存(malloc不会将内存归零,因此它甚至不为NULL)。你应该做的是什么;
cur->next_num = malloc( sizeof( numlist ) );
cur = cur->next_num;
cur->next_num = NULL; // explicitly NULL-cap, because of issue mentioned above.
最后,NewList在结尾处仍为NULL。您应该在第一个malloc行之后使用NewList = cur;
。
在实际代码中,您可以将大部分内容放入可重用的函数中,但是为了学习这些修补程序应该足够了。
此外,在您提及的最后一个元素打印后崩溃可能是由于NULLing问题。就我所见,你的while
循环本身很好。
答案 1 :(得分:0)
您没有为NewList
分配内存。
cur = NewList;
cur = malloc(sizeof(numlist));
必须是:
NewList= malloc(sizeof(numlist));
cur = NewList;
是的,必须为每个元素分配内存。
答案 2 :(得分:0)
#include <stdio.h>
#include <stdlib.h>
typedef struct number_list {
int num;
struct number_list *next_num;
} numlist;
numlist *NewList(int value){
numlist *newp;
newp = malloc(sizeof(numlist));
if(newp){
newp->num = value;
newp->next_num = NULL;//initialize!
}
return newp;
}
int main() {
numlist *cur, *pointer;
numlist *newList=NULL;
cur = NewList(5);
newList = NewList(9);
newList->next_num = cur;
cur = newList;
pointer=cur;
while (pointer!=NULL) {
printf("%d ", pointer->num);
pointer=pointer->next_num;
}
return 0;
}