2012-03-05 74 views
0

我在C中做了一个基本的LinkedList,我有创建,添加和工作。除了在看似随机数量的获取调用(第96次调用失败,列表中包含94个元素)之后得到一个段错误,访问当前节点上的下一个指针会导致段错误。C - Segfault当访问非空指针的成员结构

此行导致段错误while(cur->next != null && i < index)我已检查并且在发生段错误之前cur没有返回空内存地址。它也崩溃在第二个循环的崩溃它(第二个printf只输出0)。 这是整个get函数

void *linkedList_get(LinkedList list, int index) 
{ 
    Node *cur = list.head; 
    int i = 0; 
    if(index != 0) 
    { 
     while(cur->next != null && i < index) 
     { 
      cur = cur->next; 
      printf("I %i\n", i); 
      printf("%i\n", cur); 
      i++; 
     } 
    } 
    if(index == i) 
     return cur->data; 
    return null; 
} 

这是节点结构

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

这是如果需要http://pastebin.com/hpWA8tb8整个代码(注意,这是我的第一个C程序,所以它可能是一个有点草率和我不释放任何内存)

+1

可能不是你的bug的来源,但你应该修改你的上面的函数来检查以确保list.head在取消引用cur-> next之前不是NULL。 – selbie

+1

如果您在调试器下运行该程序,发生段错误时调用堆栈会是什么样子? –

+0

我在使用Code :: Blocks和Mingw32时出于某种原因调试器拒绝工作,这已经调试了我作为初学C程序员非常难以调试的许多段错误。 – UberMouse

回答

1

createEmptyNode实际上并没有返回n。这意味着链表中使用的节点指针实际上是假的(并指向内存中的任何位置)。许多其他创建功能也是如此。

您应该在启用警告的情况下进行编译,这可能会引发此问题。 (例如,在GCC上使用-Wall)。

一般来说,如果在C程序中有任何内存错误,那么在错误被触发后,您无法完全理解它的行为。所以我不会声称修复这个将会使它工作。 ;-)还有一个错误,你在一个节点中设置数据,指定指针而不是指针的内容(为此应该使用类似memmove的内容,明确传递内容的大小)。

+0

哇,我不能相信我忘记了每个函数的返回值。尽管如此,它仍然在崩溃。 – UberMouse

+0

你会推荐使用valgrind吗? – minus

+0

我从来没有使用过valgrind,尽管我已经读过很多我应该去的地方!我有时在MSVC中运行代码,可以检测到一些内存错误(可能类似于valgrind)。 – Edmund

1

埃德蒙很可能找到了答案。但我也抓到了这一点:

这是危险的错误,特别是在64位操作系统上,并且编译sizeof指针大于sizeof(int)。

Node *n = malloc(sizeof(int) * 3); 

它应该阅读:

Node *n = malloc(sizeof(Node)); 
1

正如爱德蒙说,可能有很多错误,在这个程序中,

我反对这一部分:

next->data = malloc(sizeof(data)); 
next->data = data; 

它分配一些内存到下一个>数据,然后立即擦除该指针,并放入一个不同的值。记忆当然会泄露,并可能导致其他后果。

+0

我还没有完全得到手动内存管理,但我确实看到这是没有意义的,所以我已经删除了malloc调用。 – UberMouse

+0

数据的类型也是void * - 您应该将数据的大小从getFilesInDir传递到linkedList_add等。 – Edmund