简体   繁体   中英

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:

  1. 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; .
  2. 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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM