the programme have runtime error when it want to add nodes to linked list (in executing append function).
i tested 'create' and 'prepend' function they do their parts correctly.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data ;
struct Node* next ;
};
struct Node* Head=NULL ;
struct Node* create(int ,struct Node*);
struct Node* prepend(int ,struct Node*);
struct Node* traverse(struct Node*);
struct Node* append(int ,struct Node*);
int main()
{
int data =4 , i ;
Head = prepend(data,Head);
for(i=0;i<3;i++){
scanf("%d",&data);
append(data,Head);
}
return 0;
}
create func for adding new nodes
struct Node* create(int data ,struct Node* Head){
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node*));
if(newNode == NULL){
printf("Error\n");
exit(0);
}
newNode -> data = data ;
newNode -> next = Head ;
return newNode ;
}
adding new node at the first of linked list:
struct Node* prepend(int data ,struct Node* Head){
struct Node* newNode = create(data,Head);
Head = newNode ;
return Head ;
}
for returning last created Node:
struct Node* traverse(struct Node* Head){
struct Node* cursor = Head ;
while(cursor->next != NULL || cursor->next != Head){
cursor = cursor->next ;
}
return cursor ;
}
for adding new node to end of the linked list:
struct Node* append(int data ,struct Node* Head){
struct Node* newNode = create(data,Head);
struct Node* cursor = traverse(Head);
cursor->next = newNode ;
return newNode ;
}
you're not allocating enough bytes with
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node*));
sizeof(struct Node *) is the size of a pointer, and your structure holds a pointer + another field, so that's undefined behaviour.
a correct way (using sizeof on the dereferenced pointer to get the proper size & not casting the return value of malloc):
struct Node* newNode = malloc(sizeof(*newNode));
the second issue is in your traverse function. When you do cursor = cursor->next, cursor can be NULL and you're testng cursor->next at the next iteration. Just iterate on the list & memorize the last non-NULL node instead (and drop the test for Head being the next element, because it's just not possible:
struct Node* traverse(struct Node* Head){
struct Node* cursor = Head;
struct Node* retval = cursor;
while (cursor != NULL) {
retval = cursor;
cursor = cursor->next;
}
return retval;
}
Change this :
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node*));
to this:
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
The Segmentation Fault error comes from the traverse function and in the while's condition. It seems that NULL value can not be used in comparison and I now wonder why! By the way change this function as follow then try again:
struct Node* traverse(struct Node* Head){
struct Node* cursor = Head ;
while(cursor->next){
if(cursor->next == Head)
break;
cursor = cursor->next ;
}
return cursor ;
}
Related
The following code is not working. The linked list uses a structure called node that has two fields int data, and struct node* next. I defined two head nodes, struct node* head1 and struct node* head2 globally.
void insert(struct node* h, int data) //h is the head node
{
struct node* temp=(struct node*)malloc(sizeof(struct node));
temp->data=data;
temp->next=NULL;
if(h==NULL)
{
h=temp;
}
else
{
struct node* ptr=h;
while(ptr->next!=NULL)
{
ptr=ptr->next;
}
ptr->next=temp;
}
}
Your h is local to insert and will be destroyed once control exits insert function.
Also any changes done to h inside insert will not affect the original head.
Solution:
You can pass the reference of original head to insert in order to retain changes made in insert as below.
void insert(struct node **h, int data) //h is the head node
{
struct node* temp=(struct node*)malloc(sizeof(struct node));
temp->data=data;
temp->next=NULL;
if(*h == NULL)
{
*h=temp;
}
else
{
struct node* ptr = *h;
while(ptr->next!=NULL)
{
ptr=ptr->next;
}
ptr->next=temp;
}
}
and you call insert as below.
struct node *head = NULL;
insert(&head,1);
I have a question regarding passing the head of a linked list in C through a function. So the code goes something like this:
#include <stdio.h>
//Defining a structure of the node
struct node {
int data;
struct node* next;
};
void insert (struct node* rec, int x) {
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->data = x;
temp->next = NULL;
rec = temp; // head and rec is now pointing to the same node
}
void print(struct node* rec){
printf("%d", rec->data); //error occurs here
puts("");
}
main(){
struct node *head = NULL; //head is currently pointing to NULL
insert (head, 5); //Passing the head pointer and integer 5 to insert()
print(head);
}
So as you see, the error occurs when I tried printing rec->data. Why did the error occur? I thought since the pointer rec and head are all pointing to the same node in the heap, there should not be any problem?
Thank you.
You could pass a struct node** as suggested by #sje397.
However, I would suggest the following design (which, in my opinion is easier to reason about too):
/* returns the new head of the list */
struct node *insert (struct node* current_head, int x) {
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->data = x;
temp->next = current_head;
return temp;
}
and use it like
head = insert(head, 5);
In this case I would also rename the function something like push_front.
Just for completeness, I think #sje397 meant something like the following (Typical linked list code rewritten again and again by every C programmer...):
void insert(struct node **head, int x) {
struct node* new_head = (struct node*)malloc(sizeof(struct node));
new_head->data = x;
new_head->next = *head;
*head = new_head;
}
In C there is no pass by reference.
Your insert function isn't inserting a node in the list, its just changing the node which the head points to. Because of temp->next = NULL the list will always contain two nodes.
Another error is that you're just modifying a local copy of the head node.
To fix this You have 3 choices:
-You can make the head node global
-You can pass a pointer to the head node(pointer to pointer) to the function.
-You can return the modified head node by the function.
Redefine the insert function to:
void insert (struct node** rec, int x) {
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->data = x;
temp->next = NULL;
*rec = temp; // head and rec is now pointing to the same node
}
I'm trying to understand linked lists. I created this code which is supposed to give me experience with linked lists. When I run this code I get 0, though the output should be 10,9,8,7,6,5,4,3,2,1,0. Could someone help me figure this out?
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int value;
struct node *next;
}node;
node * addnode (node *ptr, int value);
void traverse(node *ptr);
int main (void)
{
int i;
node *ptr,*root;
root=(node *)malloc(sizeof(node));
ptr=root;
root->value=0;
root->next=0;
for(i=1;i>10;i++)
ptr=addnode(ptr,i);
traverse(ptr);
return(0);
}
void traverse(node *ptr)
{
printf("%d\n",ptr->value);
if(ptr->next) /*assuming that the pointer to the next node is initialized to NULL, so if its NULL then the if codeblock won't execute*/
traverse(ptr->next);
}
node * addnode (node *ptr, int value)
{
node *newnode;
newnode=(node *)malloc(sizeof(node));
newnode->value=value;
newnode->next=ptr;
return(newnode);
}
There are two problems with your code:
Ideally, you would do traverse(root) instead of traverse(ptr).
You are adding nodes at the beginning of your linked list, when you should add them on the end of the list.
You can do it like this (source):
void Push(struct node** headRef, int newData) {
struct node* new_node =
(struct node*) malloc(sizeof(struct node));
new_node->data = newData;
new_node->next = *headRef;
*headRef = new_node;
}
which in your case would look like:
void addnode(struct node** headRef, int newData) {
struct node* new_node =
(struct node*) malloc(sizeof(struct node));
new_node->value = newData;
new_node->next = *headRef;
*headRef = new_node;
}
Then you add nodes like this: addnode(&root, some_value);
I want to make a double linked list and I have a problem with accessing fields in the struct. This is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int val;
struct node * next;
struct node * prev;
}node;
void insert(int val, node **head)
{
node * temp= *head;
node * temp2=(node *)malloc(sizeof(node));
node * temp3=(node *)malloc(sizeof(node));
temp2->val=val;
temp2->prev=NULL;
temp2->next=*head;
*head=temp2;
temp2->next->prev=temp2;
}
void print(node* head)
{
node* temp=head;
while(temp!=NULL)
{
printf("%d ", temp->val);
temp=temp->next;
}
}
int main()
{ node * head=NULL;
insert(1, &head);
insert(2, &head);
print(head);
return 0;
}
I get a crash at temp2->next->prev, and I don't understand why. Am I not allowed to access the prev field of the temp2->next node? I tried writing (temp2->next)->prev but also doesn't work. Is there any way that I cant make that work?
When you insert the first node, *head, and therefore temp->next, is NULL. Check that case:
void insert(int val, node **head)
{
node *temp= malloc(sizeof(*temp));
temp->val = val;
temp->prev = NULL;
temp->next = *head;
*head = temp;
if (temp->next) temp->next->prev = temp;
}
(I've removed the unused variables and lost the cast on malloc.)
A doubly linked list should probably have a tail, too. In that case, update the tail when you append an item at the head of an empty list.
try this:
void insert(int val, node **head)
{
if(*head == NULL){
node * temp2=(node *)malloc(sizeof(node));
temp2->val=val;
*head = temp2;
}
else{
node * temp= *head;
node * temp2=(node *)malloc(sizeof(node));
temp2->val=val;
temp2->prev=NULL;
temp2->next=temp;
temp->prev = temp2;
}
}
Most likely head was not initialized
As I have understood you always insert a new node before the head though in double linked list you have to add new nodes usually at the tail of the list. As a double linked list usually have two sides then there is a sense to define two functions: push_front and push_back. Your function insert corresponds to function push_front.
Nevertheless function insert could look the following way
void insert( int val, node **head )
{
node *temp = ( node * )malloc( sizeof( node ) );
temp->val = val;
temp->prev = NULL;
temp->next = *head;
if ( *head ) ( *head )->prev = temp;
*head = temp;
}
It would be better if you would define one more structure named as for example List (or whatever) and that could be defined as
struct List
{
node *head;
node *tail;
};
Also you could add one more data member - a count of the nodes in the list, For example
struct List
{
node *head;
node *tail;
size_t count;
};
Also do not forget to write a function that would delete all nodes of the list when it is not needed any more.
I have this c program that delete the first node and show the node head data.
int Delete(struct node** head){
struct node *temp = headRef;
headRef = headRef->next;
tmp->next=NULL;
free(temp);
int headNode = headRef->data;
return headNode; }
I was not able to delete the first node but it give me error of request member 'data' and 'struct'
I don't understand where if headRef comes from.
Secondly, you only need to pass the head node into the function, therefore you need
struct node* head, not struct node** head
This is my code, I hope it helps you.
int Delete(struct node* head) {
struct node* temp = head;
struct node* nextNode = head -> next;
int headData = head -> data;
temp -> next = NULL;
free(temp);
head = nextNode;
return headData;
}