【问题标题】:Segmentation fault in program but GDB doesn't show line number程序中出现分段错误,但 GDB 不显示行号
【发布时间】:2014-01-26 09:45:01
【问题描述】:

我正在用 C 编写 List ADT。我是 C 新手,正在尝试将代码从 Java 翻译成 C。但是,当我测试 List ADT 时,我不断遇到分段错误。

当我在 GDB 中调试程序时,出现以下错误:

程序收到信号SIGSEGV,分段错误。 getIndex()中的0x0000000000400be8

然后当我输入命令“where”时,我收到以下消息:

#0 0x0000000000400be8 in getIndex()

#1 0x0000000000400806 in main()

下面的代码是发生错误的方法getIndex():

int getIndex(List L) {
   int returnIndex = 0;
   if (offEnd(L)) return -1;
   else {
      NodeRef currIndex = L->curr;
      while (currIndex != L->front) {
         ++returnIndex;
         currIndex = currIndex->prev;
      }
   }
   return returnIndex;
}

作为参考,offEnd() 方法和 NodeRef 的结构是:

int offEnd(List L) {
   if (L == NULL) {
      printf("List Error: Calling offEnd() on NULL List\n");
      exit(1);
   }
   return (L->length == 0);
}

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

typedef Node* NodeRef;

typedef struct ListObj {
   NodeRef front;
   NodeRef back;
   NodeRef curr;
   int length;
} ListObj;

NodeRef newNode(int node_data) {
   NodeRef N = malloc(sizeof(Node));
   N->data = node_data;
   N->next = NULL;
   N->prev = NULL;
   return (N);
}

任何帮助都将不胜感激,因为我是 C 的新手并且正在苦苦挣扎。谢谢。

【问题讨论】:

  • 您在哪个操作系统上使用哪个编译器(以及哪个版本)进行编码?
  • ListListObj 一样吗?显示更多代码,尤其是List 的定义(例如typedef)...
  • -1 因为你没有解释什么是List ....
  • while (currIndex != L->front) { : currIndexNULL?
  • 这是一个非常有用的问题,因为我在 FreeBSD 上遇到了这个问题,并通过 Google 找到了这个问题。

标签: c gdb segmentation-fault


【解决方案1】:

假设您使用 GCC 编译器,您应该在编译时包含所有警告和调试信息

 gcc -Wall -g yoursource.c -o yourbinary

当然,改进代码直到完全没有警告为止。

也许getIndex 是用NULL 参数调用的。您可以添加

#include <assert.h>

yoursource.c 文件和代码的开头附近:

int getIndex(List L) {
  int returnIndex = 0;
  assert (L != NULL);
  if (offEnd(L)) return -1;
  else {
    NodeRef currIndex = L->curr;
    while (currIndex != L->front) {
       ++returnIndex;
       currIndex = currIndex->prev;
    }
 }
 return returnIndex;
}

了解assertassert(3)

顺便说一句,我认为指针在 C 语言中非常重要,以至于您总是需要明确它们。所以有一个typedef struct listnode_st ListNode; 并声明ListNode* L(或者可能是ListObj* l,我不知道List 是什么)而不是List L。我也更喜欢大写的宏,所以建议用小写的 l 声明 int getindex(ListNode*l) 并相应地调整该函数的主体。

最后,你的newNode 是错误的:malloc 可能会失败,你总是应该处理这样的失败。所以开始吧

NodeRef newNode(int node_data) {
  NodeRef N = malloc(sizeof(Node));
  if (N == NULL) { perror("malloc Node"); exit (EXIT_FAILURE); };

提防memory leaks;阅读有关C dynamic memory allocationpointer aliasingundefined behaviorgarbage collection 的更多信息;仔细阅读malloc(3);考虑(至少在 Linux 上)使用像 valgrind 这样的内存泄漏检测器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-04
    • 2011-09-26
    • 2021-12-26
    • 2017-01-11
    • 1970-01-01
    • 2021-03-29
    • 2015-09-15
    • 2012-10-24
    相关资源
    最近更新 更多