0

我的程序中有以下四个结构

struct SType{
    int type;//struct type
};

struct S1{
};

struct S2{
};

struct S3{
};

我使用以下代码将这些结构的状态保存在一个文件中:

无效存储(结构 SType s1,无效 *s){

//open file and stuff
//s points to either one of the last three structs
fwrite(&s1,sizeof(s1),1,file);  fwrite(s, size, 1, file);
//structs are always saved in the file in pairs of SType and either one of the last three structs 
}

现在,当我尝试使用以下代码从文件中检索该对的第二个结构时,出现分段错误。那么如何使用 fread() 检索任意结构类型的对象?

void read(){
void *record;
//read struct SType object from the file 
//now read the second struct of the pair   
fread(record,size,1,file);
}
4

2 回答 2

3

你必须读入有效的记忆。void意思是“我不知道”,系统不能也不会为你猜出那个值!!你所拥有的是:

void read(){
void *record;// This pointer currently is a random value - this will cause a fault when you try and copy data into it by calling:
fread(record,size,1,file);
}

它应该是:

void read(){
void *record;
len = ?; // Your program needs to know this. You must know which structure it is somehow if you are to cast it later. Therefore you should know its size.
record = malloc(len); // Where len has been previously found to be AT LEAST big enough to read into
fread(record,size,1,file);
}

正如您所说,您的代码不是伪代码,然后还要在您的结构中添加一些内容,以便它们不为空。还建议您在阅读完结构后对其进行处理,例如从您的 fread.return 中返回 void *。

希望有帮助。

于 2013-10-09T10:13:01.517 回答
1

您读取了未初始化指针的记录,我想您应该先分配内存。

void *record = maloc( size )

并且不要忘记释放...

我可以建议你使用联盟吗?

您的类型定义将如下所示:

struct SType{
    int type;//struct type
};
struct S1{
};

struct S2{
};

struct S3{
};

union S{
    S1 s1;
    S2 s2;
    S3 s3;
};

现在读写可以这样完成:

SType stype;
S s;

fread(&stype,sizeof(stype),1,file);
size = ???  //get according to type
fread(&s,size,1,file); 
// your data will be stored according to type in s.s1, s.s2 or s.s3   

size = ???  //get according to type
fwrite(&stype,sizeof(stype),1,file);
fwrite(&s,size,1,file);

下一阶段,是将 Type 与其余部分统一起来:

struct S{
    int type;//struct type
    union {
        S1 s1;
        S2 s2;
        S3 s3;
    }s;
};
/* in case you don't care about loosing file space, 
   you can read\write all in a single operation like this:
 */ 
S s;
fread(&s,sizeof(s),1,file); 
// now according to the type you take s.s.s1, s.s.s2 or s.s.s3.   
fwrite(&s,sizeof(s),1,file);

/* if you do care about loosing file space, you work like before */
S s;
fread(&s.type,sizeof(int),1,file);
size = ??? //get according to type
fread(&s.s,size,1,file); 
// as before, you take s.s.s1, s.s.s2 or s.s.s3.   
size = ???  //get according to type
fwrite(&s.type,sizeof(int),1,file);
fwrite(&s.s,size,1,file);
于 2013-10-09T10:45:37.250 回答