I'm trying to understand linked lists. I have this code here:
#include<stdio.h>
#include<stdlib.h>
struct node {
int value;
struct node *next;
};
typedef struct node node_t;
void printlist(node_t *head){
//temp is just a pointer to a node; not actually a node
node_t *temp;
temp = head;
printf("%d ", temp->value);
while (temp != NULL){
temp = temp->next;
printf("%d ", temp->value);
}
}
node_t create_new_node(int value){
node_t node;
node.value = value;
node.next = NULL;
return node;
}
int main(){
node_t *head;
node_t tmp;
tmp = create_new_node(32);
head = &tmp;
tmp = create_new_node(87);
tmp.next = head;
head = &tmp;
printlist(head);
return 0;
}
But when I run the program, nothing shows. My question is, why doesn't create_new_node work here? Wouldn't node be statically allocated? I know pointers would make it work, I just want to see why this doesn't. I tried using malloc here, it didn't work, probably because it's not assigned to a pointer.
Thank you!
CodePudding user response:
Style notes: modern C has compound literals, and you do not need to separately declare and initialize, so let's just write:
node_t temp = (node_t){.value=32, .next=NULL};
Rewriting your code to cut out the excess and streamline printlist
.
#include <stdio.h>
#include <stdlib.h>
typedef struct node node_t;
struct node {
int value;
node_t *next;
};
void printlist(node_t *head) {
//temp is just a pointer to a node; not actually a node
node_t *temp = head;
while (temp != NULL) {
printf("%d ", temp->value);
temp = temp->next;
}
}
int main() {
node_t tmp = (node_t){ .value=32, .next=NULL };
node_t *head = &tmp;
printlist(head);
tmp = (node_t){ .value=87, .next=NULL };
tmp.next = head;
head = &tmp;
printlist(head);
return 0;
}
The fact that tmp
is not a pointer means that it represents memory space for exactly one node. You end up with exactly one node that circularly points to itself.
Your create_new_node
function should dynamically allocate a new node.
node_t *create_new_node(int value) {
node_t *result = malloc(sizeof(node_t));
if (!result) return NULL;
result->value = value;
result->next = NULL;
return result;
}
CodePudding user response:
Here in your function there is no creation of new node taking place just the previously existing node is being assigned the values while to add new node add this....and pass the address of node to which you want to add next node as parameter
//take funtion as void becasue no need to return anythning
void create_new_node(node_t* node){
//create a new node and pointing the pointer of base to the new node
node.next = malloc(sizeof(struct node));
/*there is no need to return any value just simple assign to it as it will
decrease time complexity.Like instead of creating and then assgning next
and then return just simply assign to reduce time complextity*/
}
Add the constructor to your defination of struct node that will assign the value NULL on everytime creation to your next pointer.
CodePudding user response:
Let's simplify your main()
function.
int main() {
node_t *head;
node_t tmp;
tmp = create_new_node(32);
head = &tmp;
tmp = create_new_node(87);
printf("%d\n", head->value); // 32 or 87?
return 0;
}
Should it print 32
or 87
?
If you can understand that it actually prints 87
, instead of 32
, then everything will become clear.
Let's look at the code line by line.
1. node_t tmp;
There is some stack memory allocated to store a node_t
object.
Let's say a node_t
object takes up 16 bytes, so tmp
now occupies an area of memory whose address is
0x100, 0x101, 0x102, ..., 0x10f
2. tmp = create_new_node(32);
A node_t
with value 32
now is stored in the above area of memory, from 0x100
to 0x10f
.
3. head = &tmp;
head
now stores the address of tmp
, which is 0x100
.
4. tmp = create_new_node(87);
The exactly same memory area, starting with 0x100
, now stores a node with value 87
.
The old node with value 32
is gone at this moment.
5. printf("%d\n", head->value);
Print out the value of the node where head
points, i.e. at 0x100
, which is 87
.
It is desirable to need to understand
tmp = create_new_node(value);
The right-hand side returns a node_t
(a struct, which could be large, not a pointer), and puts it in the memory occupied by the tmp
in the left-hand side. So this assignment is storing the real value, not the address.
By the way, there is one more problem in your program.
while (temp != NULL){
temp = temp->next;
printf("%d ", temp->value);
}
You should check the next node is not null, instead of checking the node itself, before moving on to the next one.