简体   繁体   中英

Linked list segmentation fault

I am practicing by writing a linked list that will take in numbers from the user in ascending order and tell you what the unique numbers you used are. I keep getting a segmentation fault after it inders my findUnique function and my while loop I have set up to print the list out before it enters isnt printing anything. This is just practice with linked list so any help would be appreciated.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

typedef struct number{

    int num;
    struct number* next;
}Number;

Number *addterm(Number*, int);
void findUnique(Number*);

int main(void){

    Number *Number_List = NULL;
    int digit = 1;

    printf("Enter numbers in ascending order(enter 0 to stop): ");
    scanf("%d", &digit);

    while(digit != 0){
        addterm(Number_List, digit);
        printf("Enter numbers in ascending order(enter 0 to stop): ");
        scanf("%d", &digit);
    }
    printf("\ntest 1\n");

    Number *ptr = Number_List;
    while(ptr){
        printf("%d ", ptr -> num);  
        Number_List = ptr -> next;          
    }
    printf("\ntest 2\n");
    printf("\n");

    findUnique(Number_List);


    return 0;
}

Number *addterm(Number* list, int userIn){
    Number *newNum = (Number *) malloc ( sizeof (Number) );
    newNum->num = userIn;
    newNum->next = list;

    if(list == NULL){
        return newNum;
    }
    Number *ptr = list;

    while( ptr->next != NULL ){
        ptr = ptr->next;
    }
    ptr->next = newNum;
    return list;
}
void findUnique(Number* list){

    int print, temp;
    print = list->num;
    temp = print;
    printf("The unique numbers you entered are %d", temp);

    while( list ){
        print = list->num;
        if(print == temp){
            continue;
        }
        else{
        temp = print;
        printf(" %d", temp);
        }
        list = list -> next;
    }
    return;
}

Error 1:

addterm(Number_List, digit);

should be

Number_List = addterm(Number_List, digit);

Your forgot to update your list pointer.

Error 2:

while(ptr){
    printf("%d ", ptr -> num);  
    Number_List = ptr -> next;          
}

should be

while(ptr){
    printf("%d ", ptr -> num);  
    ptr = ptr -> next;          
}

This is generating an infinity loop.

Error 3:

newNum->next = list;  //In addTerm()

should be

newNum->next = NULL;

New nodes don't have a next node set. This also generated an infinity loop.

Error 4:

if(print == temp){
        continue;
}

should be

if(print == temp){
        list = list->next;
        continue;
    }

Another infinity loop.

I had an attempt at this problem, and I believe the error is in your findUnique function. These issues are already covered by @MatzZze below, and it will help fix your current code.

Alternatively, you can try this approach.It shows an alternative way to remove the duplicates from a linked list, and updates the list appropriately. The extra code I included was to just help run the program.

Here it is:

#include <stdio.h>
#include <stdlib.h>

typedef int data_t;

typedef struct node node_t;

struct node {
    data_t num;
    node_t *next;
};

typedef struct {
    node_t *head;
    node_t *foot;
}list_t;

list_t *make_empty_list(void);
list_t *add_term(list_t *list, data_t value);
void read_terms(list_t *list);
void print_unique_terms(list_t *list);
list_t *unique_terms(list_t *list);
void print_list(list_t *list);
void free_list(list_t *list);

int
main(int argc, char const *argv[]) {
    list_t *list;

    list = make_empty_list();

    read_terms(list);

    printf("Your numbers are:\n");
    print_list(list);

    unique_terms(list);

    printf("The unique numbers you entered are:\n");
    print_list(list);

    free(list);

    return 0;
}

void
read_terms(list_t *list) {
    int digit;

    printf("Enter numbers in ascending order(enter 0 to stop): ");
    while (scanf("%d", &digit) == 1) {
        if (digit == 0) {
            break;
        } else {
            add_term(list, digit);
        }
    }
}

list_t
*add_term(list_t *list, data_t value) {
    node_t *node;
    node = malloc((sizeof(*node)));
    node->num = value;
    node->next = NULL;

    if (list->foot == NULL) {
        list->head = list->foot = node;
    } else {
        list->foot->next = node;
        list->foot = node;
    }
    return list;
}

list_t
*unique_terms(list_t *list) {
    node_t *node = list->head;

    while (node != NULL && node->next != NULL) {
        if (node->num == node->next->num) {
            node->next = node->next->next;
        } else {
            node = node->next;
        }
    }
    return list;
}

void
free_list(list_t *list) {
    node_t *curr, *prev;
    curr = list->head;
    while (curr) {
        prev = curr;
        curr = curr->next;
        free(prev);
    }
    free(list);
}

void
print_list(list_t *list) {
    node_t *node = list->head;

    while (node != NULL) {
        printf("%d ", node->num);
        node = node->next;
    }
    printf("\n");
 }

list_t
*make_empty_list(void) {
     list_t *list;
     list = malloc(sizeof(*list));
     list->head = NULL;
     list->foot = NULL;
     return list;
}

These are great answers and they will certainly help you out with this code.

HOWEVER, I suggest the following: The real answer to this question is that this is a linked list as you probably know:

+------+     +------+     +------+
| data |     | data |     | data |
+------+     +------+     +------+
| next |---->| next |---->| next |----> NULL
+------+     +------+     +------+
   ^
   |
 START (Keep track of the whole list.)

The biggest dangers you can run into is with your next and start pointers. Now to answer your question in a way which will always help you do the following:

  1. Enable debugging in your IDE and place a breakpoint in your program entrypoint. Use the Step over tool in rapid fire until the program faults. Now you know which line is causing it.

  2. Place a break point on that line and debug to that spot and determine when the pointer which is causing the problem gets set.

  3. Many IDE's offer a tool to place a 'watch' on a variable that will break the program at a point only if the variable you specify is equal to a value you specify, in this case I'd advise NULL.

  4. Since right now you're getting segfaults you will need to look in places you have loops as you are likely iterating past the bounds of your list.

Learning debugging techniques is the correct solution to this problem!

Good luck!

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