fread into structs array of fault fault

时间:2013-04-08 20:07:08

标签: c file struct fread calloc

我一直在研究这段代码已经有一段时间了,我遇到了一个我似乎无法调试的段错误。这是相关的代码:

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] - &gt; x)上失败;” line或对fread调用后分配的内存的任何其他访问权限。我知道我传入的是一个有效的文件,因为它可以正确读取halo_num。它还从fread调用中收集关于Halo对象的正确信息,就像我调用fread并检查返回它返回halo_num一样。

谢谢!

2 个答案:

答案 0 :(得分: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字节的距离,并解释该位置的字节 - 这些是某些floatint的值的一部分读入,而不是指针 - 并尝试访问任何位置的x组件是错误解释的结果。

你应该

typedef struct Halo Halo;

并使用halo_catalog[10000].x来解决该问题。

另一个问题是fread会返回已成功读取的项目数,如果小于请求的数字,则仍然可以是正数。

捕获fread的返回值,并使用它来确定读数是否完全成功。此外,在尝试打印halo_catalog[10000].x之前,请确保10000是有效索引。

答案 1 :(得分:2)

这实际上是否编译?

问题是halo_catalog是一个指向数组的指针,而不是一个指针数组。您应该使用printf("%f\n", halo_catalog[10000].x);

我假设10000仅用于测试目的?因为我看不到保证在halo_catalog中有10000条记录。