1

私はしばらくの間、このコードに取り組んできましたが、デバッグできないように見えるセグ フォールトに遭遇しました。関連するコードは次のとおりです。

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 *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_num が返されるため、fread 呼び出しから Halo オブジェクトに関する正しい情報も収集します。

ありがとう!

4

2 に答える 2

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*)where ポイントからバイトの距離で、その場所のバイトを解釈します-これは、ポインターではなく、読み込まれたいくつかの s またはs のhalo_catalog値の一部です-そして、その誤解の結果である任意の場所のコンポーネントにアクセスしようとします.floatintx

あなたがすべき

typedef struct Halo Halo;

halo_catalog[10000].xその問題を修正するために使用します。

別の問題は、fread正常に読み取られたアイテムの数を返すことです。それが要求された数よりも小さい場合でも、正の数になる可能性があります。

の戻り値をキャプチャしfread、それを使用して読み取りが完全に成功したかどうかを判断します。また、印刷を試みる前に、10000 が有効なインデックスであることを確認してhalo_catalog[10000].xください。

于 2013-04-08T20:22:36.290 に答える
2

それは実際にコンパイルされますか?

問題は、halo_catalog がポインターの配列ではなく、配列へのポインターであることです。あなたが使用している必要がありますprintf("%f\n", halo_catalog[10000].x);

10000はテスト目的のためだけだと思いますか?halo_catalog に 10000 件のレコードがあることを保証するものは何も見たことがなかったからです。

于 2013-04-08T20:09:58.653 に答える