Linked list in C seg faults - c

Having seg fault erros with my code posted below. I am new to C and have been having some trouble with it. Basically in my main I made a struct node* head (pointer to a struct node) and assigned it to NULL. I then send the struct node * head to the push function that should insert user defined integers into the front of the list. I believe I am having issues inside the push function, any help would be very aprecciated.
~Thanks
//node.h
struct node{
int val;
struct node* next;
};
int length(struct node *);
struct node* push(struct node *, int);
void print(struct node *, int);
//node.c
#include "./node.h"
#include<stdlib.h>
#include<stdio.h>
int length(struct node *current){
if(current->next != NULL)
return 1 + length(current->next);
else
return 1;
}
struct node* push(struct node *head, int num){
struct node *temp = malloc(sizeof(struct node));
temp->val = num;
temp->next = head;
head = temp;
return head;
}
void print(struct node* head, int size){
printf("The list is %i", size);
printf(" long \n");
struct node* temp;
temp = head;
while(temp != NULL){
printf("%d", temp->val);
printf(" ");
temp = temp->next;
}
printf(" \n");
}
//main program
#include "./node.h"
#include<stdlib.h>
#include<stdio.h>
int main(){
char ans;
int num;
struct node* head = NULL;
do{
printf("Enter a integer for linked list: ");
scanf("%d", &num);
head = push(head, num);
printf("Add another integer to linked list? (y or n) ");
scanf("%1s", &ans);
}while(ans == 'y');
print(head, length(head));
return 0;
}

scanf will read n+1 characters into the provided buffer when you use %ns because of the null terminator.
Use a buffer of size 2 (char ans[2];) and check the first character (ans[0] == 'y'). You will also no longer need to take the address of ans when calling scanf).

Related

Segmentation fault while dealing with linked list in c

I am trying to implement polynomial addition using linked list. I have only coded a small part of it where i accept the input into first polynomial and while i was testing the code it kept throwing a segmentation fault error. I have sprinkled some random printf statements to try to debug the code.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
struct node{
struct node* next;
int coeff, power;
};
struct node* createNode(){
struct node *temp;
temp=(struct node*)malloc(sizeof(struct node));
temp->next = NULL;
return temp;
}
struct node* poly1,poly2,poly3;
void createList(struct node* head){
int ch=0;
struct node* temp;
struct node* newNode = createNode();
head=NULL;
temp=NULL;
while(ch!=-1){
printf("Enter coefficient and power");
scanf("%d",&newNode->coeff);
scanf("%d",&newNode->power);
if( head ==NULL){
printf("123123123");
temp = newNode;
head = newNode;
printf("bbbbbb");
}else{
printf("aaaaaaaa");
temp->next = newNode;
temp = newNode;
}
printf("Enter -1 to exit");
scanf("%d",&ch);
printf("9999");
}
printf("1");
}
void display(struct node* head)
{
struct node *temp;
temp=head;
if(temp==NULL)
printf("LL not present");
else
{
while(temp!=NULL)
{
printf("%dx^%d ",temp->coeff,temp->power);
temp=temp->next;
}
}
}
void main(){
printf("Enter the data for the first polynomial\n");
createList(poly1);
printf("%d",poly1->coeff);
display(poly1);
}
This is the output i am getting for it-
Enter the data for the first polynomial Enter coefficient and power3 2
123123123bbbbbbEnter -1 to exit9 9999Enter coefficient and power 1 1
1 1 aaaaaaaaEnter -1 to exit-1 Segmentation fault
Interestingly when i change the second last line of my while loop from
scanf("%d",&ch);
to ch=-1; the output that i get has none of the random printf i added to debug :
Enter the data for the first polynomial Enter coefficient and power3 2
Segmentation fault
I dont understand what the difference is between both of these cases. Also whats the issue with segmentation fault being thrown around?
As noted above you need to pass in the address of poly1, I made it a local rather than a global variable. Then you need to create a new node per loop iteration in createList(). Removed debugging output (use a macro and write something sensible in case you want to leave it in). Prefer for to while loops for iteration.
#include <stdio.h>
#include <stdlib.h>
struct node{
struct node* next;
int coeff, power;
};
struct node* createNode(){
struct node *temp;
temp=(struct node*)malloc(sizeof(struct node));
temp->next = NULL;
return temp;
}
void createList(struct node **head){
int ch;
*head = NULL;
do {
printf("Enter coefficient and power: ");
struct node* newNode = createNode();
if(scanf("%d %d",&newNode->coeff, &newNode->power) != 2) {
// TBD: free list
*head = NULL;
printf("scanf failed\n");
return;
}
if(!*head){
*head = newNode;
} else {
(*head)->next = newNode;
}
printf("Enter -1 to exit: ");
if(scanf("%d",&ch) != 1) {
// TBD: free list?
// *head = NULL;
printf("scanf failed\n");
return;
}
} while(ch!=-1);
}
void display(struct node *head)
{
if(!head) {
printf("LL not present");
return;
}
for(; head; head=head->next) {
printf("%dx^%d ", head->coeff, head->power);
}
printf("\n");
}
int main(void){
printf("Enter the data for the first polynomial\n");
struct node *poly1;
createList(&poly1);
display(poly1);
}
and example session:
Enter the data for the first polynomial
Enter coefficient and power: 1 2
Enter -1 to exit: 0
Enter coefficient and power: 3 4
Enter -1 to exit: -1
1x^2 3x^4
Consider reading a char instead of a int for the loop control (newline is continue, and 'q' could be quit). If you separate the UI from data structure manipulation then it will much easier to test your code (non-interactively). Write a function to free your list, and call that in the end. This will allow you to use a tool like valgrind to search for memory leaks.
For the first part of your question, I can't reproduce the issue. I changed the line scanf("%d", &ch); to ch = -1, and my output was: "123123123bbbbbbEnter -1 to exit99991", which does not match your output. Are you sure that your code compiled correctly?
For the second part of your question, the reason why you are getting a segment fault, is because you are not actually creating a new node for every polynomial. You only have one instance of a node, and in the while-loop, you constantly change the attributes of that node. In order for this to work, you have to create a new node for every polynomial, and insert that node into the list.
Some stylistic remarks:
It makes more sense to immediately assign a variable when you declare it. For example, in your code it happens a lot that you create a variable like this: int num;, and on the next line: num = 5;, for different datatypes and values. It makes more sense to immediately write: int num = 5;.
You declared poly1, poly2 and poly3, but you are only using poly1. You declared these variables globally, and then changed the contents of poly1 in a function. In order to optimally scope your variables, it makes more sense to write: struct Node *poly1 = createList();.
The code with these remarks implemented looks like this:
#include <stdio.h>
#include <stdlib.h>
struct Node {
struct Node* next;
int coeff;
int power;
};
struct Node* createNode(){
struct Node *head = malloc(sizeof(struct Node));
//error check if malloc failed.
if(head == NULL) {
exit(-1);
}
printf("Enter coefficient and power\n");
scanf("%d %d", &head->coeff, &head->power);
head->next = NULL;
return head;
}
struct Node *createList(){
int ch=0;
struct Node* head = NULL;
struct Node* temp = NULL;
while(ch != -1){
struct Node* newNode = createNode();
if(head == NULL) {
head = newNode;
temp = newNode;
} else {
temp->next = newNode;
temp = newNode;
}
printf("Enter -1 to exit");
scanf("%d",&ch);
}
return head;
}
void display(struct Node* head) {
while(head != NULL) {
printf("%dx^%d ",head->coeff,head->power);
head=head->next;
}
}

Error in a simple program of entering elements at beginning of a linkedlist and displaying it in c programming

This is my code for program to enter elements in beginning of a linked list and print the linked list which is working perfectly fine(i am getting correct output for it) -
#include <stdio.h>
#include <stdlib.h>
// this is insertion of a node in begining of a linked list
typedef struct Node
{
int data;
struct Node *next;
} n;
void Insert(struct Node** head,int x)
{
struct Node *temp = (n *)malloc(sizeof(struct Node));
temp->data = x;
temp->next = *head;
*head = temp;
}
void Print(struct Node* head)
{
struct Node *temp = head;
printf("The linked list is:");
while (temp != NULL)
{
printf("%d,", temp->data);
temp = temp->next;
}
printf("\n");
}
int main()
{
struct Node *head;
head = NULL;
int n, i, x;
printf("Enter how many numbers you want?\n");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("Enter the number in the linkedlist\n");
scanf("%d", &x);
Insert(&head,x);
Print(head);
}
return 0;
}
for context the output is
Enter how many numbers you want?
6
Enter the number in the linkedlist
1
The linked list is:1,
Enter the number in the linkedlist
2
The linked list is:2,1,
Enter the number in the linkedlist
3
The linked list is:3,2,1,
Enter the number in the linkedlist
4
The linked list is:4,3,2,1,
Enter the number in the linkedlist
5
The linked list is:5,4,3,2,1,
Enter the number in the linkedlist
6
The linked list is:6,5,4,3,2,1,
now just to see if my concepts of pointers and pointer to structure is clear i modified the Print() function in code as while rest of he program remain same
#include <stdio.h>
#include <stdlib.h>
// this is insertion of a node in begining of a linked list
typedef struct Node
{
int data;
struct Node *next;
} n;
void Insert(struct Node** head,int x)
{
struct Node *temp = (n *)malloc(sizeof(struct Node));
temp->data = x;
temp->next = *head;
*head = temp;
}
void Print(struct Node* head)
{
struct Node *temp = head;
printf("The linked list is:");
// while (temp != NULL)
// {
// printf("%d,", temp->data);
// temp = temp->next;
// }
// printf("\n");
do{
printf("%d,", temp->data);
temp = temp->next;
}while((temp->next)!= NULL);
printf("\n");
}
int main()
{
struct Node *head;
head = NULL;
int n, i, x;
printf("Enter how many numbers you want?\n");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("Enter the number in the linkedlist\n");
scanf("%d", &x);
Insert(&head,x);
Print(head);
}
Print(head);
return 0;
}
Now while i did the dry run where i am getting correct result ,the output i am getting is wrong,for context the output coming is
Enter how many numbers you want?
5
Enter the number in the linkedlist
1
The linked list is:1,
--------------------------------
Process exited after 5.156 seconds with return value 3221225477
Press any key to continue . . .
while i only made changes in Print() function why is'nt the compiler accepting the rest of the elements in linkedlist as input ? assuming there is some mistake in Print() function
Such function implementation
void Print(struct Node* head)
{
struct Node *temp = head;
printf("The linked list is:");
// while (temp != NULL)
// {
// printf("%d,", temp->data);
// temp = temp->next;
// }
// printf("\n");
do{
printf("%d,", temp->data);
temp = temp->next;
}while((temp->next)!= NULL);
printf("\n");
}
is incorrect.
Firstly it does not check whether the passed pointer is equal to NULL.
Secondly the condition in the do-while loop
}while((temp->next)!= NULL);
can invoke undefined behavior if after this statement within the loop
temp = temp->next;
the pointer temp again is equal to NULL (when the list contains one node). Because in this case a null pointer is used to access memory. Or in other case when the list contains more than one node the last node will not be outputted.

How to solve the pointer issue in the double linked list below?

Recently I learnt about doubly linked lists, and I have tried to write some code in C to implement them. The program below is supposed to receive integer inputs form the user and put them into a list with a maximum of ten integers. However, when I input the values and then print them, only the first and last values are output. How would one solve this issue?
Here is the code:
`#include <stdio.h>
#include <stdlib.h>
struct node {
struct node* prev;
int num;
struct node* next;
};
struct node *head,*p;
struct node* create_first_node(int x)
{
struct node *new = (struct node*)malloc(sizeof(struct node));
new->num=x;
new->prev=NULL;
new->next=NULL;
head=new;
p=head;
return new;
}
void add_node(int x)
{
struct node*new=(struct node*)malloc(sizeof(struct node));
new->num=x;
new->prev=p;
p->next=new;
(new->next)=NULL;
new=p;
}
void print_list(){
struct node *temp= head;
printf("\nThe list is:\n");
while (temp!=NULL)
{
printf("%d\t",temp->num);
temp=temp->next;
}
}
int main(){
int in[10];
int len,i;
head=NULL;
printf("How many nodes would you like?(Max=10) \n");
scanf("%d",&len);
for (i = 0; i < len; i++)
{
if (head == NULL && i==0)
{
printf("Enter Value for node %d\n",i+1);
scanf("%d",(in+i));
create_first_node(in[0]);
}
else
{
printf("Enter Value for node %d\n",i+1);
scanf("%d",(in+i));
add_node(in[i]);
}
}
print_list(head);
return 0;
}`

Linked list append function adding an extra empty node at the beginning

struct node{
char name[50];
double grade;
struct node* next;
};
void append(struct node* root){
int n;
printf("Enter the number of students: ");
scanf("%d",&n);
while(n !=0){
struct node* temp;
temp=(struct node*)malloc(sizeof(struct node));
printf("\nEnter the name of the student: ");
scanf("%s",&temp->name);
printf("\nEnter the grade for the student named %s: ",temp->name);
scanf("%f",&temp->grade);
temp->next=NULL;
if(root==NULL){
root=temp;
}else{
struct node* iterate=root;
while(iterate->next != NULL){
iterate=iterate->next;
}
iterate->next=temp;
}
n--;
}
}
int listLength(struct node* root){
struct node* temp = root;
int counter=0;
while(temp !=NULL){
counter++;
temp=temp->next;
}
return counter;
}
int main()
{
struct node* root = NULL;
append(&root);
//printList(&root);
printf("Node length: %d",listLength(&root));
return 0;
}
This is what I have so far as I'm starting out with linked lists. I tried to make it so I can append to multiple linked lists with the function. So I'd just create a different root pointer in main and call the append function with it as a parameter to add nodes.
This seems to work, however, it adds an extra empty node at the beginning of the list. This node doesn't contain any data. So for example, if I add 4 students to the list the nodeLength function would return 5.
Change this:
void append(struct node* root)
to this:
void append(struct node** root)
so that you make the changes last even when append() terminates.
Of course then you will have to use *root instead of root inside the body of that function.
PS: Do I cast the result of malloc? No.
struct node{
char name[50];
double grade;
struct node* next;
};
struct node * append(struct node* root){
int n;
printf("Enter the number of students: ");
scanf("%d",&n);
while(n !=0){
struct node* temp;
temp=(struct node*)malloc(sizeof(struct node));
printf("\nEnter the name of the student: ");
scanf("%s",&temp->name);
printf("\nEnter the grade for the student named %s: ",temp->name);
scanf("%f",&temp->grade);
temp->next=NULL;
if(root==NULL){
root=temp;
}else{
struct node* iterate=root;
while(iterate->next != NULL){
iterate=iterate->next;
}
iterate->next=temp;
root=iterate;
}
n--;
}
return root; }
int nodeLength(struct node* root){
struct node* temp = root;
int counter=0;
while(temp !=NULL){
counter++;
temp=temp->next;
}
return counter;
}
int main()
{
struct node* root = NULL;
root= append(root);
//printList(&root);
printf("Node length: %d",nodeLength(root));
return 0;
}
Check this code to understand a bit. Will explain more.
And don't cast the return type of malloc.
Here what you are doing will work fine for if you correctly changed the parameter to struct node** but yes it can be done more easily like this(example shown above). It's natural and more intuitive rather than using double pointer.

Appending Linked List in C seg fault errors

I am having some trouble adding integers to the end of my linked list. I am very new to C and had part of my program working properly (the push function). I want to return a pointer to a struct node, and I am not quite sure where I am going wrong in my append function.
~Thanks.
enter code here
//node.h
#ifndef NODE_H
#define NODE_H
struct node{
int val;
struct node *next;
};
int length(struct node *);
struct node* push(struct node *, int); //adds integer to front of list.
struct node* append(struct node *, int); //adds integer to back of list.
void print(struct node *, int);
#endif
//node.c
#include "./node.h"
#include<stdlib.h>
#include<stdio.h>
int length(struct node *current){
if(current->next != NULL)
return 1 + length(current->next);
else
return 1;
}
struct node* push(struct node *head, int num){
struct node *temp = malloc(sizeof(struct node));
temp->val = num;
temp->next = head;
head = temp;
temp = NULL;
return head;
}
struct node* append(struct node *current, int num){
if(current != NULL){
append(current->next, num);
}
else{
struct node* temp = malloc(sizeof(struct node));
temp->val = num;
temp->next = NULL;
current = temp;
return current;
}
}
void print(struct node* head, int size){
printf("The list is %i", size);
printf(" long \n");
struct node* temp;
temp = head;
while(temp != NULL){
printf("%d", temp->val);
printf(" ");
temp = temp->next;
}
printf(" \n");
}
//Main
#include "./node.h"
#include<stdlib.h>
#include<stdio.h>
int main(){
char ans[2];
int num;
struct node* head = NULL;
do{
printf("Enter a integer for linked list: ");
scanf("%d", &num);
head = append(head, num);
printf("Add another integer to linked list? (y or n) ");
scanf("%1s", ans);
}while(*ans == 'y');
print(head, length(head));
return 0;
}
I think what is missing is that the recursive part of the function needs to set current->next. This has the effect of setting every node's next pointer to what it was until you get to the end of the list, when it is set to the newly malloced node.
struct node* append(struct node *current, int num){
if(current != NULL){
current->next = append(current->next, num);
return current;
}
else {
struct node* temp = malloc(sizeof(struct node));
if (temp == NULL) abort();
temp->val = num;
temp->next = NULL;
return temp;
}
}

Resources