MS535
MS535

Reputation: 47

Troubleshooting segmentation fault (core dumped) in linked lists

Node *orderedInsert(Node *p, int newval)
/* Allocates a new Node with data value newval
   and inserts into the ordered list with 
   first node pointer p in such a way that the
   data values in the modified list are in 
   nondecreasing order as the list is traversed.
*/
{
   Node* current = NULL;
   Node* prev = NULL;
   Node* newNode = (Node*)malloc(sizeof(Node));
   newNode->next = NULL;
   newNode->data = newval;

   if(newNode == NULL)
      printf("Could not allocate memory for new node");

   current = p;   

   if(p == NULL){

      current = newNode;
      newNode->next = NULL;
      newNode->data = newval;
      return  newNode;
   }
   else if(newval < p->data){
      newNode->next = p;
      p = newNode;
      return p;
   }
   else{
      prev = p;
      current = current->next;   

      while(newNode->data > current->data && current != NULL){

         prev = current;
         current = current->next;
      }
      if(current == NULL){
         prev->next = newNode;
         newNode->next = NULL;
      }
      else{
         newNode->next = current;
         prev->next = newNode;
      }
   }

}

void printList(FILE *outfile, Node *p)
/* Prints the data values in the list with 
   first node pointer p from first to last,
   with a space between successive values.
   Prints a newline at the end of the list.
*/
{

   Node* current = p;

   while(current != NULL){
      fprintf(outfile, "%d ",current->data);
      current = current->next;
   }
   fprintf(outfile, "\n");

}

int main(int argc, char * argv[])
{
   assert(argc == 3);
   Node * p = NULL;
   int newval, retval;
   int op;

   FILE *in = fopen(argv[1],"r");
   assert(in != NULL);
   FILE *out = fopen(argv[2],"w");
   assert(out != NULL);
   do {
      op = fgetc(in);
   }  while (op != EOF && isspace(op));

   while(op != EOF && op != 'q') {
      switch(op) {
     case 'i':
        fscanf(in,"%d",&newval);
        p = orderedInsert(p,newval);
        printList(out,p);
        printList(stdout,p);
        break;
     case 'c':
        clearList(&p);
        break;
     default:
        fclose(in);
        fclose(out);
        return 0;
      }
      do
     op = fgetc(in);
      while (op != EOF && isspace(op));
   }

   fclose(in);
   fclose(out);
   return 0;
}

I am having trouble debugging the code with this error. Is there something obvious I am missing in my code and/or do you have any tips with debugging this error? I am just finding myself lost as where to start besides the fact that it does not even get past the first list entry (when list is empty).

Thanks

EDIT: I have put up revised code and am now only getting the segmentation fault when entering a number larger than the first in the list.

Upvotes: 1

Views: 77

Answers (1)

vsnyc
vsnyc

Reputation: 2257

Adding some general notes about debugging C/C++ programs.

GDB is a good tool, you have to attach it to your executable and then run the program. There is no gui mode, but people have built gui wrappers around it e.g. DDD

I find it easier to use IDE if I can, depending on the environment you are using MS Visual Studio, Netbeans CPP, Eclipse CDT, QtCreator and the latest C++ IDE from Jetbrains CLion should be some tools than can help you code better.

Test this out, it doesn't run into a segmentation fault for me. I'm testing on ubuntu 14.04 with g++ version (Ubuntu 4.8.2-19ubuntu1) 4.8.2. Logic errors are probably present, since I wasn't very clear about the logic behind reading from file1 and then inserting into the file2

Compile: g++ Node.cpp

Run: ./a.out /home/vsnyc/tmp/1.txt /home/vsnyc/tmp/2.txt

File: 1.txt
i 12 i 4 i 6 i 9 q

Node.cpp is below:

//Filename: Node.cpp
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

struct Node {
    Node *next;
    int data;
};

Node *orderedInsert(Node *p, int newval)
/* Allocates a new Node with data value newval
   and inserts into the ordered list with 
   first node pointer p in such a way that the
   data values in the modified list are in 
   nondecreasing order as the list is traversed.
*/
{
   Node* current = NULL;
   Node* prev = NULL;
   Node* newNode = (Node*)malloc(sizeof(Node));
   newNode->next = NULL;
   newNode->data = newval;

   if(newNode == NULL)
      printf("Could not allocate memory for new node");

   current = p;   

   if(current == NULL){

      current = newNode;
      newNode->next = NULL;
      newNode->data = newval;
      return current;
   }
   else if(newval < current->data){
      newNode->next = current;
      current = newNode;
      return current;
   }
   else{
      prev = p;
      current = current->next;   

      while(newNode->data > current->data && current != NULL){

         prev = current;
         current = current->next;
      }
      if(current == NULL){
         prev->next = newNode;
         newNode->next = NULL;
      }
      else{
         newNode->next = current;
         prev->next = newNode;
      }
   }
}

void clearList(Node ** p) {
}


void printList(FILE *outfile, Node *p)
/* Prints the data values in the list with 
   first node pointer p from first to last,
   with a space between successive values.
   Prints a newline at the end of the list.
*/
{

   Node* current = p;

   while(current != NULL){
      fprintf(outfile, "%d ",current->data);
      current = current->next;
   }

}


int main(int argc, char * argv[])
{
   assert(argc == 3);
   Node * p = NULL;
   int newval, retval;
   int op;

   FILE *in = fopen(argv[1],"r");
   assert(in != NULL);
   FILE *out = fopen(argv[2],"w");
   assert(out != NULL);
   do {
      op = fgetc(in);
   }  while (op != EOF && isspace(op));

   std::cout << op << "\n";

   while(op != EOF && op != 'q') {
      switch(op) {
     case 'i':
        fscanf(in,"%d",&newval);
        std::cout << newval << "\n";
        p = orderedInsert(p,newval);
        printList(out,p);
        printList(stdout,p);
        break;
     case 'c':
        clearList(&p);
        break;
     default:
        fclose(in);
        fclose(out);
        return 0;
      }
      do
     op = fgetc(in);
      while (op != EOF && isspace(op));
   }

   fclose(in);
   fclose(out);
   return 0;
}

Upvotes: 1

Related Questions