问题
I've just started out with C and I think the whole pointers/malloc/free is driving me mad. I tried to define a simple linear recursive data structure and loop through it, printing each element that I've looped through. (Code as below).
However, I'm getting Segmentation Fault: 11 as soon as I try to move to the next element to "insert" a new element
#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;
}
Furthermore, I have on another larger program a while-loop that functions exactly like this while-loop here except on a "filled" recursive structure. Hence I don't actually need to create any new element, just run through and print each element out. However, in that moment where the loop prints the last element, it crashes with Segmentation Fault: 11 again. I'm guessing it's likely because I tried to do pointer = pointer->next_num
. How do I then correctly run through such a data structure correctly on C anyway?
回答1:
You have a few conceptual issues. First you need to know the distinction between the pointer and the memory it points to;
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
That means that in these two lines:
cur = NewList;
cur = malloc(sizeof(numlist));
the second completely replaces the first assignment.
Now this line:
cur = cur->next_num;
Well next_num
hasn't been set yet, so cur is set to garbage memory (malloc doesn't zero the memory so it's not even NULL). What you should do is;
cur->next_num = malloc( sizeof( numlist ) );
cur = cur->next_num;
cur->next_num = NULL; // explicitly NULL-cap, because of issue mentioned above.
Finally, NewList is still NULL at the end. You should use NewList = cur;
after your first malloc line.
In real code, you would put most of this into reusable functions, but for learning those fixes should suffice.
Also the crash after printing the last element which you mention is likely because of the NULLing issue. Your while
loop itself is fine as far as I can see.
回答2:
You are not allocating memory for NewList
.
cur = NewList;
cur = malloc(sizeof(numlist));
It must be:
NewList= malloc(sizeof(numlist));
cur = NewList;
And yes, you must allocate memory for each element.
回答3:
#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;
}
来源:https://stackoverflow.com/questions/16384641/looping-through-recursive-list-in-c