I'm brand new to programming in C and trying to figure out pointers. I thought I'd start with trying to write a simple linked list program. The idea in addNote was to iterate along the chain of pointers until I found a pointer to a NULL instead of a struct node then change that pointer to point to the new node I'm going to add. I figured out this would require pointers to pointers, at least it seems like it should. I can get it to add the first node but when I call it the second time to my surprise the address of the new struct I'm creating is the SAME as the previous one?! This I do not understand. Or are there many more fundamental things wrong here? Lol, quite possible as I've never worked with pointers and C before. Thank you for any help!
#include <stdio.h>
struct node{
int value;
struct node* next;
};
void addNode(int value, struct node** base){
struct node newnode;
newnode.value = value;
newnode.next = NULL;
struct node** nodeptr = base;
while(*nodeptr != NULL){
nodeptr = &(*nodeptr)->next;
}
printf("%d :- value\n",value);
printf("%p :- base\n",base);
printf("%p :- *base\n",*base);
printf("%p :- nodeptr\n",nodeptr);
printf("%p :- *nodeptr\n",*nodeptr);
printf("%p :- nodeaddress\n\n",&newnode);
*nodeptr = &newnode;
}
int main(){
struct node* base = NULL;
addNode(12,&base);
addNode(13,&base);
return 0;
}
Here is a sample output I get from the printf debugging code:
12 :- value
0000007D6EBFF818 :- base
0000000000000000 :- *base
0000007D6EBFF818 :- nodeptr
0000000000000000 :- *nodeptr
0000007D6EBFF7C0 :- nodeaddress
13 :- value
0000007D6EBFF818 :- base
0000007D6EBFF7C0 :- *base
0000007D6EBFF7C8 :- nodeptr
0000000000000000 :- *nodeptr
0000007D6EBFF7C0 :- nodeaddress
I wasn't expecting the address of new node to be the same the 2nd time I called addNode, since it creates a new struct node?
CodePudding user response:
When *nodeptr = &newnode;
executes, the prior node never gets its .next
updated.
*nodeptr = &newnode;
itself is no good as newnode
is a local object and &newnode
is invalid when the function returns.
Instead allocate a node and put it in the list.
// This simple example adds `value` to the front of the list.
void addNode(int value, struct node** base){
struct node *new_node = malloc(sizeof new_node[0]);
if (new_node == NULL) {
Handle_OutOfMemeory(); // Perhaps quit the program?
}
new_node->value = value;
new_node->next = *base;
*base = new_node;
}
Advanced
To add to the end, I would first re-organize the list and keep track of its tail, not the head. The tail would point to the head. Then adding to the end or beginning can occur in O(1) time.