简体   繁体   中英

How to avoid segfault when adding to a sorted linked list?

I need to create a new function when adding a new element, it places it in the list so that the list stays in sorted order. I am not sure if my implementation is correct, my first try, with my group members, gave a segmentation fault. When I tried to do it on my own, it did not do anything. Any help will be appreciated. Here is my code:

header file:

typedef struct s{
        int value;
        struct s *next, *previous;
} node, *node_ptr;

c file:

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

void
print_list(node_ptr list) {
   // walk the list to print out the contents
   while (list) {
        printf("%d ",list->value);
        list = list->next;
   }
   printf("\n");
}

void delete_list(node_ptr list) {
   // walk the list to delete the elements
   node_ptr t;
   while (list) {
        t = list;
        list = list->next;
        free(t);
   }
}

node_ptr new_node(int value) {
   node_ptr t = (node_ptr)malloc(sizeof(node));
   t->value = value;
   t->next = t->previous = NULL;
   return t;
}

node_ptr add_to_back(node_ptr list, int value) {
   node_ptr t = list;
   node_ptr s = new_node(value);
   // special case: starting with an empty list
   if (t == NULL) return s;
   // at this point we know there is a least one element in
   // the list
   while (t->next != NULL)  // walk the list looking for the last element 
     t = t->next;
   // we are at the end so now we arrange the pointers
   t->next = s;
   s->previous = t;
   return list;
}

// my implementation after some research
node_ptr add_sorted(node_ptr list, int value) {
        node_ptr temp = list;
        node_ptr newNode;

        if(temp == NULL || temp->value < newNode->value)
        {
                newNode->next = temp;
                temp = newNode;
        }
        else
        {
                while(temp != NULL && temp->value < value)
                {
                        temp = temp->next;
                }
                newNode->next = temp->next;
                temp->next = newNode;
        }
        return newNode;
}

// second implementation with team
/*
node_ptr add_sorted2(node_ptr list, int value) {
        // This is the function you need to implement
        // when adding a new element place it in the list so that the list stays in sorted order.
        node_ptr temp = list;
        node_ptr n = new_node(value);

        if(temp == NULL)
        {
                temp->value = value;
                temp->next = NULL;
                return n;
        }
        else if(temp->next != NULL) {   
        while(temp->next != NULL) {

                 if(temp->value <= value) {
                        n->next = temp->next;
                        temp->next = n;
                        return n;               
                }
                else if(temp->value > value) {
                        temp = temp->next;
                }
                else {
                        temp->next = n;
                        return n;
                }
        }
        }
        return n; 
}
*/

int
main() {
   int in_val;
   node_ptr my_list = NULL;
   node_ptr sorted_list = NULL;
   scanf("%d",&in_val);
   while (in_val > 0) {  // going to read input until see 0 or negative
           my_list = add_to_back(my_list,in_val);
           sorted_list = add_sorted(sorted_list,in_val);
           scanf("%d",&in_val);
   }
   printf("List:\n");
   print_list(my_list);
   printf("Sorted List:\n");
   print_list(sorted_list);
   delete_list(my_list);
   delete_list(sorted_list);
}

The segmentation fault is clear to me, you are using an uninitialized pointer here

if(temp == NULL || temp->value < newNode->value)
//                                  ^

Or ANY OTHER newNode 's dereference anywhere , because newNode is never initialized in your code.

If temp == NULL , and you didn't initialize newNode yet then undefined behavior .

Adding a node to a list while preserving order is easy,

  1. Create the new node
  2. If succeeded creating it, traverse the list until the next node is greater|smaller ( depending on the ordering that you desire ) than the new node.
  3. When you find it, link current's node next to the new node and the next node should be new node's next .

And that is all.

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