2012-03-05 73 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