結構體 st 包含三個 char[],fwrite/fread 讀寫文件。運行時輸出亂碼,**增加一個 int dummy 成員後突然正常**。
struct st {
char name[4]; // 偏移 0,大小 4
char age[3]; // 偏移 4,大小 3
char tel[9]; // 偏移 7,大小 9
}; // 總大小 = 16?實際因對齊可能為 16 或 20
tel 後填充 1~3 字節使結構體大小為 4 的倍數(sizeof(int) 對齊)。/Zp、-fpack-struct)導致填充不同,**文件二進制格式不穩定**。int dummy 後struct st {
char name[4];
char age[3];
char tel[9];
int dummy; // 強制 4 字節對齊,結構體大小固定為 20
};
#pragma pack(1) 取消填充(跨平台需謹慎)#pragma pack(push, 1)
struct st {
char name[4];
char age[3];
char tel[9];
};
#pragma pack(pop)
void writeStruct(FILE* fp, const struct st* s) {
fwrite(s->name, 1, sizeof(s->name), fp);
fwrite(s->age, 1, sizeof(s->age), fp);
fwrite(s->tel, 1, sizeof(s->tel), fp);
}
void readStruct(FILE* fp, struct st* s) {
fread(s->name, 1, sizeof(s->name), fp);
fread(s->age, 1, sizeof(s->age), fp);
fread(s->tel, 1, sizeof(s->tel), fp);
}
struct FileHeader { uint32_t magic; uint16_t version; uint16_t structSize; };
// 寫入頭部,再寫入結構體,讀取時校驗版本與大小
寫入文件前 printf("size=%zu, name=%s, age=%s, tel=%s\n", sizeof(struct st), s[i].name, s[i].age, s[i].tel); 確認內存數據正確,再排查文件讀寫。
結構體直接 fwrite 受**記憶體對齊/填充**影響極大,**增加成員改變對齊只是巧合掩蓋問題**。生產代碼必須採用逐字段序列化或顯式打包,確保二進制格式穩定、跨平台兼容。