2013-04-09 98 views
1

嘿我發現了一個使用malloc與一個結構數組適合我想要做得很好,但是當我去結合它與qsort我需要按結構的「數字」值排序沒有太多的運氣。該代碼符合罰款沒有錯誤,但實際上並沒有運行,只是崩潰。由於我是初學者,我不知道是什麼原因造成了這個問題。如果有人能夠闡明這一點,那就非常謝謝!malloc示例與qsort崩潰?

// Example code from "a tutorial on 'dynamic' arrays in C" 
// http://fydo.net 

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

typedef struct DATA{ 
    char *name; 
    int number; 
} DATA; 

DATA *the_array = NULL; 
int  num_elements = 0; // To keep track of the number of elements used 
int  num_allocated = 0; // This is essentially how large the array is 
int compare(struct DATA *, struct DATA *); 
typedef int (*compfn)(const void*, const void*); 

int compare(struct DATA *elem1, struct DATA *elem2) 
{ 
    if (elem1->number < elem2->number) 
     return -1; 

    else if (elem1->number > elem2->number) 
     return 1; 

    else 
     return 0; 
} 



int AddToArray (DATA item) 
{ 
    if(num_elements == num_allocated) { // Are more refs required? 

     // Feel free to change the initial number of refs and the rate at which refs are allocated. 
     if (num_allocated == 0) 
      num_allocated = 3; // Start off with 3 refs 
     else 
      num_allocated *= 2; // Double the number of refs allocated 

     // Make the reallocation transactional by using a temporary variable first 
     void *_tmp = realloc(the_array, (num_allocated * sizeof(DATA))); 

     // If the reallocation didn't go so well, inform the user and bail out 
     if (!_tmp) 
     { 
      fprintf(stderr, "ERROR: Couldn't realloc memory!\n"); 
      return(-1); 
     } 

     // Things are looking good so far, so let's set the 
     the_array = (DATA*)_tmp; 
    } 

    the_array[num_elements] = item; 
    num_elements++; 

    return num_elements; 
} 

int main() 
{ 
    // Some data that we can play with 
    char *names[6] = { "Steve", "Bill", "George", "fydo", "Dave", "Jim" }; 
    int numbers[6] = { 42, 33, 15, 74, 5, 20 }; 
    int i; 

    // Populate! 
    for (i = 0; i < 6; i++) 
    { 
     DATA temp; 

     temp.name = malloc((strlen(names[i]) + 1) * sizeof(char)); 
     strncpy(temp.name, names[i], strlen(names[i]) + 1); 
     temp.number = numbers[i]; 

     if (AddToArray(temp) == -1) // If there was a problem adding to the array, 
      return 1;    // we'll want to bail out of the program. You 
            // can handle it however you wish. 
    } 

    //sort by number: 
    qsort((void *) &the_array, 6, sizeof(struct DATA), (compfn)compare); 

    // Regurgitate! 
    for (i = 0; i < 6; i++) 
    { 
     printf("%s's number is %d!\n", the_array[i].name, the_array[i].number); 
    } 

    // Deallocate! 
    for (i = 0; i < 6; i++) 
    { 
     free(the_array[i].name); 
    } 

    free(the_array); 

    // All done. 
    return 0; 
} 
+0

您的調試器顯示什麼? – md5 2013-04-09 18:12:44

+0

崩潰在哪裏?通過調試器運行代碼並確定發生崩潰的位置。 – rerun 2013-04-09 18:13:46

回答

2

您正在以錯誤的方式傳遞數組。

應該

qsort(the_array, 6, sizeof(struct DATA), (compfn)compare); 

qsort預計作爲第一個參數的指針到的數據進行排序開始,這是the_array不是它的地址&the_array既然你這樣

DATA *the_array = NULL; 
宣佈它

輸出將是:

Dave's number is 5! 
George's number is 15! 
Jim's number is 20! 
Bill's number is 33! 
Steve's number is 42! 
fydo's number is 74! 

會發生什麼,qsort認爲該陣列從the_array的地址開始,並開始訪問其中不允許的其他內存區域。

編輯

我有4000個字tryed它,不能讓它崩潰,這裏是我修改了代碼從文件讀取,(strdup是UST得心應手相當於malloc + strcpy

char name[100]; 
while(1 == scanf("%s", name)) { 
    DATA temp; 
    temp.name = strdup(name); 
    temp.number = rand(); 
    if (AddToArray(temp) == -1) 
     return 1;    
} 

執行是這樣的:

out.exe < lorem.txt 

的數據是科爾ectly排序,打印和免費版

+0

哇,那簡單!謝謝!只是一個問題,那裏有什麼需要(void *)?我注意到它可以正常使用或不使用它? – user2261877 2013-04-09 18:22:02

+1

不需要它,這就是爲什麼我刪除它(如果它在那裏不傷害)。 'void *'可以指向任何類型的數據。你可以把它看作是一種通用的。由於'qsort'必須適用於每個數據類型數組,因此該函數的簽名需要使用'void *'完成。同樣的事情適用於比較功能。但要訪問您的數據,您必須退回到它。 – A4L 2013-04-09 18:27:55

+0

乾杯。可能比在這裏開始一個新的線程更好地問這裏。當語言達到很多數字時,使用上述代碼釋放內存時遇到問題,它只會凍結。 'for(i = 0; i user2261877 2013-04-09 19:45:59