排查链表中的分段错误(核心转储)

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;
}

我在调试带有此错误的代码时遇到问题。我的代码中是否明显遗漏了什么 and/or 你有调试此错误的任何提示吗?除了它甚至没有超过第一个列表条目(当列表为空时)之外,我只是发现自己迷失了从哪里开始。

谢谢

编辑:我已经提交了修改后的代码,现在只有当输入的数字大于列表中的第一个数字时才会出现分段错误。

添加一些关于调试 C/C++ 程序的一般说明。

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

如果可以的话,我发现使用 IDE 更容易,这取决于您使用 MS Visual Studio 的环境,Netbeans CPP, Eclipse CDT, QtCreator and the latest C++ IDE from Jetbrains CLion 应该是一些可以帮助您更好地编写代码的工具。

测试一下,它不会 运行 成为我的分段错误。我正在使用 g++ 版本 (Ubuntu 4.8.2-19ubuntu1) 4.8.2 在 ubuntu 14.04 上进行测试。可能存在逻辑错误,因为我不太清楚从 file1 读取然后插入到 file2

背后的逻辑

编译:g++ Node.cpp

运行: ./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如下:

//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;
}