2016-10-11 17 views
3

我一直在爲這個問題掙扎幾個小時,而且我對目前的情況感到不知所措。這是program.c代碼:索引'mallocced'陣列時出現分段錯誤

#include <stdio.h> 
#include <stdlib.h> 
#include <assert.h> 

#define SPACE 32 
#define INITIAL 4 

typedef struct { 
    char *town; 
    char *country; 
} town_t; 

typedef struct { 
    int num_towns, current_size; 
    town_t **towns_list; 
} index_t; 

int main(int argc, char *argv[]) { 

    index_t town_index; 
    town_index.current_size = INITIAL; 
    town_index.towns_list = malloc(town_index.current_size * sizeof(*(town_index.towns_list))); 
    assert(town_index.towns_list != NULL); 

    printf("Step: %d\n", 1); 
    town_index.towns_list[0]->town = malloc(4 * sizeof(*(town_index.towns_list[0]->town))); 
    printf("Step: %d\n", 2); 
    assert(town_index.towns_list[0]->town != NULL); 

    return 0; 
} 

在Linux上,這是它的運行方式:

./program 
Step: 1 
Segmentation fault 

但在Windows打印出

program.exe 
Step: 1 
Step: 2 

如我期望,這真的沒有幫助。但是,對於Linux輸出,顯然第一個打印語句正在執行,但不是第二個,這將導致我認爲兩者之間的界限是錯誤的。特別是,我認爲做town_index.towns_list[0]正在引起我的問​​題,但我不能說爲什麼。

這是一個相對複雜的數據結構,所以也許我在某個時候迷了路。 town_index基本上是一個索引結構,其中包含當前城鎮數towns_listcurrent_size,它反映了當前可用於保存城鎮的空間。它還包含一個指向town_t的指針數組,其中包含姓名和國家字符串。

我試過使用Valgrind,但它真的沒有什麼幫助。這是一個Pastebin爲那些誰想看。

這是我在另一個程序中遇到的簡化情況,所以不要介意任何想法。

這是在VirtualBox Linux Mint 64位上。


無關的問題,如果有人可以:我如何讓Valgrind顯示精確的線?我在網上看到了其他地方,但是我的輸出只是告訴我程序和函數所在的文件夾,這沒什麼幫助。

+1

歡迎使用堆棧溢出!這聽起來像你可能需要學習如何使用調試器來遍歷代碼。使用一個好的調試器,您可以逐行執行您的程序,並查看它與您期望的偏離的位置。如果你打算做任何編程,這是一個重要的工具。進一步閱讀:[如何調試小程序](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。 –

+0

當您在第一個malloc – Toby

+1

中獲取town.index.towns_list的sizeof時,錯過了一個星號友情推薦:不要使用後綴'_t'來指示typenames,因爲它們是由標準隱式保留的,並且由POSIX標準。 ([提示](https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html)) –

回答

4

您初始化了town_index.towns_list,但不是town_index.towns_list[0],所以town_index.towns_list[0]->town是未定義的行爲。

你錯過了什麼樣

for (int i = 0; i < town_index.current_size; ++i) 
    town_index.towns_list[i] = malloc(sizeof **town_index.towns_list); 

第二個維度。

+0

啊太棒了,正是我所需要的,謝謝!這清除了它,並修復了我正在研究的更大的程序:) – Arkantos

0

town_index.towns_listtown_index.towns_list[0]是不一樣的。您初始化town_index.towns_list,但town_index.towns_list[0]等於0.通過解引用引起的崩潰town_index.towns_list[0]