2011-03-20 110 views
7

一些前言:我是一名計算機工程專業的學生,​​在3學期的Java(高達數據結構)之後參加C的第一堂課。這個問題與家庭作業有關,但是爲了解決這個問題,我除去了一些步驟。使用stdlib的qsort()對字符串數組進行排序

我有一個輸入文件,我讀入內存,使它存儲在char [9] [500]。我讀了最多500個字符串的最大長度爲8.我試圖使用stdlib內置的qsort()函數對此數組進行排序,並且存在一些內存錯誤。的代碼

重要片段:

char data[4][500][60]; 
char debug[500][9]; 
size_t count = 0; 

/* initialize file, open for reading */ 
FILE* pUserlog; 
pUserlog = fopen("userlog","r"); 

while(!feof(pUserlog)) 
{ 
    fscanf(pUserlog, "%9s %8s %16s",debug[count], data[1][count], data[2][count]); 
    fgets(data[3][count], 60, pUserlog); 
    count++; 
} 

此部分讀取數據到所述陣列。這部分感興趣的數組是「調試」。這是上面指定的數組。這裏是我的qsort比較函數:

int compare(const void* a, const void* b) 
{ 
    const char **ia = (const char **)a; 
    const char **ib = (const char **)b; 
    puts("I'm in compare!"); 
    return strncmp(*ia, *ib,8); 
} 

這是我試圖調用快速排序:

size_t debug_len = sizeof(debug)/sizeof(char*); 
printf("debug len: %d, count: %d, sizeof(char*): %d\n",debug_len,count,sizeof(char*)); 
qsort(debug,count, sizeof(char *), compare); 

我試圖在我的電話代debug_len其中計數,但我仍然段錯誤。這裏是輸出:

 
$ ./test 
debug len: 1125, count: 453, sizeof(char*): 4 
I'm in compare! 
Segmentation fault (core dumped) 

謝謝!

+0

while(!feof())是錯誤的。 feof將返回false,循環將進入,scanf將無法讀取數據,debug [count]將包含僞造數據,然後feof將返回true。你可以通過在循環後執行count來修復這種情況,但總的來說,你應該永遠不要這樣做(!feof()) – 2011-03-20 19:12:58

+1

它在哪裏段錯誤?檢查覈心轉儲以確定段錯誤發生的位置是一個很好的練習,因爲它通常會告訴你問題是什麼。 – 2011-03-20 19:14:05

回答

8

比較功能將接收指針被比較的元素。您正在有效地嘗試使用strncmp()來比較字符。由於您有指向每個字符串的指針,因此將其轉換爲char *並進行比較。

int compare(const void* a, const void* b) 
{ 
    const char *ia = (const char *)a; 
    const char *ib = (const char *)b; 
    puts("I'm in compare!"); 
    return strncmp(ia, ib, 9); 
} 

還記得,它是一個數組的數組,而不是一個指針數組。所以元素的大小應該是數組的大小,9而不是指針的4。在這一點上,僅僅使用sizeof debug[0]會更容易,因爲它是一個二維數組。如果你沒有使用合適的尺寸來做到這一點,qsort()只會破壞你的陣列。

size_t elemsize = sizeof debug[0];  /* 9 - size of each element */ 
size_t count = sizeof(debug)/elemsize; /* 500 - number of elements in array */ 
qsort(debug, count, elemsize, compare); 
3

這裏發生的事情是:你有500個字符串。現在你將所有的500個傳遞給qsort,然後它依次傳遞每個作爲第一個和第二個參數給你的比較函數。這有點像寫這個:

compare(debug[0], debug[1]) 

C編譯器傳遞的地址,當然不是實際值。但是現在,您將指向無效的指針解釋爲指向char的指針。當調用strncmp時,您的代碼會執行取消引用,但這會使(前4個字節)被視爲strncmp中的指針。但strncmp現在將嘗試解除引用垃圾「指針」(其中包含您的一個字符串的一部分),並使爆炸

爲了解決這個問題,使用char *代替char **

int compare(const void* a, const void* b) 
{ 
    puts("I'm in compare!"); 
    return strncmp((const char *)a, (const char *)b, 8); 
} 
+0

s/strncpy/strncmp/ – 2011-03-20 20:21:16

+0

@Jim Balter:謝謝,我糾正了我的答案。 – DarkDust 2011-03-21 07:17:06

相關問題