2013-04-08 31 views
1

我一直在研究這段代碼一段時間,現在我遇到了一個我似乎無法調試的seg故障。下面是相關的代碼:fread到結構數組中分段錯誤

typedef struct Halo* Halo; 
struct Halo 
{ 
    float x, y, z; 
    float vx, vy, vz; 
    int n200a; 
    float m200a; 
    float r200a; 
    int n200c; 
    float m200c; 
    float r200c; 
    int n500a; 
    float m500a; 
    float r500a; 
    int n500c; 
    float m500c; 
    float r500c; 
}; 

全局變量:

暈* halo_catalog;

失敗的函數:

int loadHaloCatalog(char *filename) 
{ 
    FILE *catalog_file; 
    long long halo_num; 

    catalog_file = fopen(filename, "rb"); 
    if (catalog_file == NULL) { 
     printf("Could not open halo catalog: %s\n", filename); 
     return -1; 
    } 
    if (fread(&halo_num, sizeof(long long), 1, catalog_file) < 0) { 
     printf("Could not read number of halos\n"); 
     return -1; 
    } 
    halo_catalog = (Halo *)calloc(halo_num, sizeof(struct Halo)); 
    if (fread(halo_catalog, sizeof(struct Halo), halo_num, catalog_file) < 0) { 
     printf("Could not read that number of halos\n"); 
     return -1; 
    } 
    printf("%f\n", halo_catalog[10000]->x); 
    printf("done\n"); 
    fclose(catalog_file); 
    return (int)halo_num; 
} 

它未能上的 「printf(」 %F \ n 「個,halo_catalog [10000] - > X);」行或對fread調用後分配的內存的任何其他訪問。我知道我傳入了一個有效的文件,因爲它可以正確讀取halo_num。它還從fread調用中收集關於Halo對象的正確信息,例如當我調用fread並檢查返回值時,它返回halo_num。

謝謝!

+0

嘗試更改'typedef struct Halo * Halo;'到'typedef struct Halo Halo;';和'halo_catalog [10000] - > x'到'halo_catalog [10000] .x'。 – 2013-04-08 20:20:24

回答

3
typedef struct Halo* Halo; 

這是一個可怕的想法,可能是你的問題的原因。

你有一個全局變量

Halo *halo_catalog; 

所以struct Halo**。但在

halo_catalog = (Halo *)calloc(halo_num, sizeof(struct Halo)); 
if (fread(halo_catalog, sizeof(struct Halo), halo_num, catalog_file) < 0) { 

您使用它,就好像它是一個struct Halo*

然後,你索引

printf("%f\n", halo_catalog[10000]->x); 

10000 * sizeof(struct Halo*)字節從那裏halo_catalog點的距離,並解釋該位置處的字節 - 它們是一些float秒或int S中的值的一部分讀入,不指針 - 並嘗試訪問任何錯誤解釋導致任意位置的組件。

你應該

typedef struct Halo Halo; 

,並使用halo_catalog[10000].x來解決這個問題。

另一個問題是fread返回它已成功讀取的項目數,如果小於請求的數字,它仍然可以是一個正數。

捕獲fread的返回值,並用它來確定讀數是否完全成功。此外,在嘗試打印halo_catalog[10000].x之前,請確保10000是有效索引。

+0

這是有道理的。謝謝! – 2013-04-08 21:34:40

2

這是否真的編譯?

問題是halo_catalog是指向數組的指針,而不是指針數組。你應該使用printf("%f\n", halo_catalog[10000].x);

我假設10000只是爲了測試的目的?因爲我沒有看到保證halo_catalog中有10000條記錄。

+0

它編譯。大約有6萬光環,所以這不是問題。 – 2013-04-08 20:19:17

+0

另外,我認爲我的問題源於對typedef的誤解。 – 2013-04-08 20:19:49

+0

我將我的定義更改爲Halo halo_catalog,而不是Halo *。 然後我改變了你的代碼並且它工作。 所以當我做typdef時,它會改變Halo *來表示一個指向Halo的指針和一個指向Halo對象數組的指針? – 2013-04-08 20:20:35