2013-10-09 152 views
0

我有以下四種結構在我的計劃閱讀結構對象無效*指針

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

struct S1{ 
}; 

struct S2{ 
}; 

struct S3{ 
}; 

我使用下面的代碼保存這些結構的狀態在一個文件中:

空隙存儲(S型結構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); 
} 
+0

我們需要更多的代碼。我*猜測*是你沒有分配內存來讀取'struct'。儘量減少你的代碼以免「垃圾」給每個人,但是一個錯誤代碼的小實例將是完美的(而不是僞代碼) – noelicus

+0

@noelicus我想讀取結構或者將其引用爲void *指針....當我讀結構時,結構對象read可以是s1,s2或s3的一種類型....稍後在我的代碼中,我將把void *指針轉換爲適當的結構類型指針。 – thunderbird

+0

我的觀點是你已經將'read' *寫入有效的記憶*,並且我猜測你可能沒有那樣做。我不得不猜測,因爲你沒有包括代碼,這是我的另一點! – noelicus

回答

2

您必須讀入有效內存。 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中返回void *。

希望有所幫助。

+0

thx它的工作...'void * pointer = malloc(sizeof(void))'讀取整個文件,而不管'fread(pointer,size,1,file)'函數中提供的'要讀取的大小'。是的,我沒有提供實際的代碼..我只是提供了用於讀寫的實際語法我認爲這就夠了 – thunderbird

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); 

下一個階段,與其他統一類型:

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);