I am trying to append one list with another . If i pass a pointer-to-the-pointer of both the lists and just display them, then , the code works fine. But if i use code to reach the NULL pointer of the first list and then equate it to the first one of the second, then it gives a segmentation fault. Please let me know what the mistake is. Code is below :
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node* next;
}*Head,*New;
void display(struct node **p)
{
struct node *curptr;
curptr=*p;
if(curptr==NULL)
printf("list is empty");
else
{
while(curptr)
{
printf("->%d",curptr->data);
curptr=curptr->next;
}
}
}
void combine(struct node **a,struct node **b)
{
//display(&(*a));
struct node *aptr;
aptr=*a;
while(aptr)
aptr=aptr->next;
aptr->next=*b;
*b=NULL;
display(&(*a));
//display(&(*a));
//display(&(*b));
}
void main()
{
Head=NULL;
New=NULL;
int choice;
while(1)
{
case 9:
{
printf("Combining two lists");
combine(&Head,&New);
break;
}
The problem is here:
while(aptr)
aptr=aptr->next;
aptr->next=*b
When you break out of the while loop aptr will be NULL next when you try to do aptr->next you get the SEGV.
To fix this break out of the loop when you reach the last node(aptr->next will be NULL) rather than aptr becoming NULL.
Something on these line:
// if fist list does not exist.
if(*a == NULL) {
*a = *b;
return;
}
struct node *aptr;
aptr=*a;
// loop till you reach the last node of fist list.
while(aptr->next)
aptr=aptr->next;
// append.
aptr->next=*b;
*b=NULL;
while(aptr)
aptr=aptr->next;
runs till aptr is NULL, after that
aptr->next=*b;
causes a segmentation fault since you dereference NULL.
Related
I'm trying to append a node to a linked list however, when I use a while loop to check if the "link" is set to NULL, the loop is being executed when it shouldn't.
It is as if the "cursor->link" was not set to NULL and the code inside the while loop is being executed, I put the print statement there just to test it and it is being executed even though "cursor->link" is set to NULL. The create function returns a "node*".
EDIT - I apologize guys, I posted this question late at night and I guess I might not have been in the best shape to express myself properly. Plus I'm still a bit confused about how to handle and work with Linked Listing (as my code probably shows). I've been given a template to work with (as in the functions append and display were preset and I've to work with them as is). The compiler did not set off any warnings with the code as is. However the program still crashes in the append function around the While loop.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node {
int data;
struct node * link;
} node;
node* create(int data,node* link) {
node* newNode = (node*)malloc(sizeof(node));
newNode->data = data;
newNode->link = link;
return newNode;
}
void append ( node **, int ) ;
void display ( node * ) ;
int main() {
node *p ;
p=NULL;
int n;
char ch[10];
do {
printf("Enter the value\n");
scanf("%d",&n);
append(&p,n);
printf("Do you want to add another node? Type Yes/No\n");
scanf("%s",ch);
}while(!strcmp(ch,"Yes"));
printf("The elements in the linked list are");
display(p);
printf("\n");
return 0;
}
/* adds a node at the end of a linked list */
void append ( node **q, int num ){
node *cursor;
if (*q == NULL) {
*q = create(num, NULL);
node *cursor = *q;
}
while(cursor->link != NULL) {
printf("1\n");
cursor = cursor->link;
}
node* newNode = create(num, NULL);
cursor->link = newNode;
}
void display ( node *q ){
node *cursor = q;
while(cursor->link != NULL) {
printf(" %d", q->data);
cursor = cursor->link;
}
printf(" %d", cursor->data);
}
As Ry mentioned, problem is with the cursor you are using in while loop, it's never initialized. Instead you are creating a new variable with the same name when *q is null. I see one more problem in your code, when list is empty you are adding new node twice. First in null check condition and then after while loop.
To fix move this line
"node *cursor = *q"
outside if condition and add a return instead. Also remove this line
"node *cursor"
Note:: I am assuming your create method has no issue.
#include<stdio.h>
#include<malloc.h>
typedef struct nde{
int data;
struct nde *next;
}node,*pnode;
void inst_beg(node *,int);
void inst_end(node *,int);
void inst_any(node *,int,int);
int del_begin(node *);
int del_end(node *);
int del_any(node*,int);
void display(node *);
main()
{
pnode head= (node *)malloc(1*sizeof(node));
head->data=0;
head->next=NULL;
inst_any(head,1,1);
inst_any(head,2,2);
// inst_any(head,3,3);
display(head);
}
void inst_any(node *head,int pos, int data){
pnode nd=(node *)malloc(1*sizeof(node));
nd->data=data;
//pnode count=(node *)malloc(1*sizeof(node));
pnode count;
count=head;
printf("head: %p",head);
printf("count: %p",count);
int i=0;
while(i<pos-1){
count=count->next; //Problem is here for inst_any(phead,2,2)
}
nd->next=count->next;
count->next=nd;
//printf("done");
}
void display(node * head){
pnode count=head;
while(count->next!=NULL){
printf("%d",count->data);
count=count->next;
}
}
Value of count is becoming null inside loop so we are not able to deference it when it is coming second time when inst_any(head,2,2) is being called. Checked with gdb that first time count is successfully being pointed to head. And same is happening for second time also. After count=head it is giving correct value for second time. Dont know what is happening after that. Why when its coming inside the loop count's value is becoming zero.
Look at this code:
while(i<pos-1){
count=count->next; //Problem is here for inst_any(phead,2,2)
}
That's the whole loop. So either your condition i<pos-1 is false right away .... or it is true and stays true, as you never modify i nor pos in your loop.
In the latter case, you walk a linked list. Eventually, you'll find the end (count->next is NULL) and still assign this NULL to count. In the next iteration, you try to dereference NULL to access ->next. Trying to dereference NULL is undefined behavior, a segmentation fault is a typical consequence.
Go and rethink your program (e.g., check whether count->next is still not NULL in your loop condition).
I have corrected your code with comments below. Please read my comments in the codes else you can not realize your mistakes. Hope this will help you.
typedef struct nde{
int data;
struct nde *next;
}node,*pnode;
void inst_beg(node *,int);
void inst_end(node *,int);
void inst_any(node *,int,int);
int del_begin(node *);
int del_end(node *);
int del_any(node*,int);
void display(node *);
void main()
{
pnode head= (node *)malloc(sizeof(node)); //No need to multiply by one
head->data=0;
head->next=NULL;
inst_any(head,1,1);
inst_any(head,2,2);
inst_any(head,3,3);
display(head);
inst_any(head,4,4); //I am adding this statement so that you can better understand where it going to be inserted
display(head);
inst_any(head,7,7);
}
void inst_any(node *head,int pos, int data){
pnode nd=(node *)malloc(sizeof(node));
nd->data=data;
//pnode count=(node *)malloc(1*sizeof(node));
pnode count;
count=head;
printf("head: %p\n",head);
printf("count: %p\n",count);
int i=0;
while(i < (pos-1)){
if(count == NULL){
printf("No position available for request pos =%d\n", pos);
return;//This condition is important. If your position is not exist in the list and count reached the end of the list just return with a error message
}
count=count->next; //Problem is here for inst_any(phead,2,2)
i++;//you must increment i
}
nd->next=count->next;
count->next=nd;//Here count must not be null, else it will create Segmentation fault. Therefore inside from while loop above we have checked whether it is null or not. If null return from this method.
//printf("done\n");
}
void display(node * head){
pnode count=head;
while(count!=NULL){//You have to correct it to print last node of the list
printf("%d\n",count->data);
count=count->next;
}
}
the posted code for the function: inst_any() initializes the data field, but fails to initialize the next field.
Suggest:
nd->data=data;
nd->next = NULL;
Then this loop:
while(i<pos-1){
count=count->next; //Problem is here for inst_any(phead,2,2)
}
fails to update the counter i so the loop never exits. Also, when the linked list does not contain enough entries this loop will run right off the end of the list. So the loop also needs to be checking that the count->next is not NULL.
I'm trying to make an array of nodes,and enter values from S[] array to it. But I keep getting a segmentation fault.
My struct looks like this:
typedef struct Node {
int num;
struct Node *next;
}ListNode;
Initialized array of S[10] with random numbers:
printf("list is:");
for(i=0;i<10; i++)
{
RN= (random()+1);
S[i]=RN;
printf("%d ",S[i]);
}
printf("\n");
Here is how I initialized my array of nodes:
ListNode *bucket[Radix];
for(j=0; j<Radix; j++)
{
bucket[i]=(ListNode*)malloc(sizeof(ListNode));
bucket[i]->next=NULL;
}
And this is the function I use to read array numbers from S[] into the array of linked list, bucket[]:
for(y=0;y<(sizeof(S)/sizeof(int));y++) // S is size of a normal array
{
digit=bucketNumber(S[y],1);// returns the first digit values
pointer= bucket[digit];
number= S[y];
insert_tail(pointer, number);
}
my insert_tail function look like this:
ListNode *insert_tail(ListNode *tail, int data)
// insert and element at tail
{
if (tail==NULL)
{ tail=(ListNode *)malloc(sizeof(ListNode));}
else
{
while(tail->next !=NULL)
tail->next = (ListNode *)malloc(sizeof(ListNode));
tail= tail->next;
}
tail->num= data;
tail->next=NULL;
}
this is the bucketNumber function:
int bucketNumber(int num,int digit)
{
int x, y;
y= 10*digit;
x= num%y;
if(digit>=2)
{
num= num%y;
x= num/(y/10);
}
return (x);
}
I think the reason for segmentation fault is that my function is not creating the links in the array properly. I'm not sure thou, there could be something else wrong!
I think the problem is in this section of insert_tail():
else
{
while(tail->next !=NULL)
tail->next = (ListNode *)malloc(sizeof(ListNode));
tail= tail->next;
}
tail->num= data;
tail->next=NULL;
Since the while() loop doesn't have curly braces following it, the below line gets executed if and only if tail->next != NULL:
tail->next = (ListNode *)malloc(sizeof(ListNode));
...which is sort of the opposite of what you want; you want to allocate a new node for next if next is NULL. As is, next is likely NULL, and so tail gets moved forward to next, but next is not allocated--it's NULL. The bottom two lines above would each cause a segmentation fault in that case, since you can't dereference a NULL pointer, which is what -> is doing.
In this code below, when I comment out the first and second call to display() function in main, It works fine. But without commenting, after adding 2nd element it says - segmentation fault.
I am new to pointers. Please suggest what might be wrong.
#include<stdio.h>
#include<malloc.h>
//-------------------------------------------------
struct node
{
int data;
struct node *next;
}*start=NULL;
//------------------------------------------------------------
void creat()
{
struct node *new_node,*current;
new_node=(struct node *)malloc(sizeof(struct node));
printf("\nEnter the data : ");
scanf("%d",&new_node->data);
new_node->next=NULL;
if(start==NULL)
{
start=new_node;
current=new_node;
}
else
{
current->next=new_node;
current=new_node;
}
}
//------------------------------------------------------------------
void display()
{
struct node *new_node;
printf("\nThe Linked List : ");
new_node=start;
while(new_node!=NULL)
{
printf("%d--->",new_node->data);
new_node=new_node->next;
}
printf("NULL\n\n");
}
//----------------------------------------------------
void main()
{
creat();
display();
creat();
display();
creat();
display();
}
output ->
$./a.out
Enter the data : 4
The Linked List : 4--->NULL
Enter the data : 6
Segmentation fault (core dumped)
This is happening because of current->next=new_node; in else block.
When you enter data second time start is declared global so its value persists between function call but as current is declared within fuunction it's scope is limited to function only.
So when you enter data second time current is null so accessing current->next causes segmentation fault.
So declare current node after start variable.
Second time you call creat, you are using an ininitialized current.
current_node is a local variable with auto storage. When you return from the function, it gets deleted.
Try adding
struct node* current = NULL;
right after you define start. Then, remove it from creat.
The offending code is:
current->next=new_node;
You are dereferencing a NUll pointer which is illegal.
What you should have done was to declare current as a global variable as well:
struct node
{
int data;
struct node *next;
}*start=NULL,*current=NULL;
This will fix your display issue as well.
I have the following code which deletes a given node from the linear single linked list.
I want to know if we can still improve this program and does it break anytime
struct node
{
int num;
struct node *next;
} ;
typedef struct node s;
void delete(struct node *first)
{
int flag = 0;
s *ptr, *lastNodePtr = NULL, *deleteNode;
deleteNode = (s*) malloc(sizeof(s));
printf("enter the node value to delete");
scanf_s("%d",&deleteNode->num);
deleteNode->next = NULL;
for (ptr=first;ptr!=NULL;ptr=ptr->next) //at least one element exist
{
if(deleteNode->num == ptr->num)
{
flag=1;
if(ptr==first) //need to delete at first place
{
free(ptr);
first = null; //i dont think we need to do this as it points to ptr and ptr is already null.
}
else // need to delete some where middle.it can be last as well.
{
lastNodePtr->next=ptr->next;
free(ptr);
}
printf("successfully deleted..");
break;
}
lastNodePtr=ptr; // taking note of last node visited..
}
if (flag==0)
{
printf("\n Couldn't find the node");
return;
}
}
if ptr is the first element in the list to delete, you set first to null, not to the next of ptr. (sideeffect: you are not able to free the the rest of the list)
your EDITH: delete should return the new Head, better make it a struct node **first parameter which changes the first element if the first is the deleted one
BTW: never cast the result of malloc.
BTW two. why use for-loop? everybody uses while-loop with linked lists
BTW three: normal variable names for linked lists are "head", "list", "next", "prev", "last" with the nice side-affect, they are all the same length, so making it neatly aligned.
struct node
{
struct node *next;
int num;
} ;
void delete(struct node **pp, int num) {
struct node *del;
for ( ;*pp; pp= &(*pp)->next) {
if((*pp)->num == num) break;
}
if (!*pp) { printf("Couldn't find the node(%d)\n", num); return; }
del = *pp;
*pp = del->next;
free(del);
}
BTW: there is nothing wrong with for() loops; they allow you to put all the loop logic on one line.