這是一個測試程序,我爲我正在編寫的一個更大的項目編寫。它與使用fwrite()將結構數據寫入磁盤然後使用fread()讀取數據相關。該結構的一個成員是動態分配的。C fread()魔法讀取動態分配的結構成員,怎麼樣?
首先,這裏是我的代碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STRING_LEN 128
struct Person {
int age;
char *name;
};
int main(int argc, const char *argv[])
{
struct Person *person = calloc(1, sizeof(struct Person));
person->age = 22;
person->name = calloc(STRING_LEN, sizeof(char));
char *name = "Name that is really, really, really, really, really, really, long.";
strncpy(person->name, name, STRING_LEN);
FILE *out_file = fopen("rw.out", "w");
fwrite(person, sizeof(struct Person), 1, out_file);
fclose(out_file);
FILE *in_file = fopen("rw.out", "r");
struct Person *person_read = calloc(1, sizeof(struct Person));
fread(person_read, sizeof(struct Person), 1, in_file);
fclose(in_file);
printf("%d %s\n", person_read->age, person_read->name);
free(person->name);
free(person);
free(person_read);
return 0;
}
而且outpout
22 Name that is really, really, really, really, really, really, long.
我的問題是,爲什麼是這方面的工作?不應該fwrite()只寫入'name'包含的地址(即字符串的開始地址)?也就是說,我將sizeof(struct Person)傳遞給fwrite(),但它正在寫入'name'指向的字符串。
更令我困惑的是fread()的行爲。同樣,如果我傳遞sizeof(struct Person),那麼'name'的實際值如何被讀取?內存如何分配?
我以前對如何使用fwrite()+ fread()的理解是,我必須「手動」寫入'name'指向的數據,「手動」讀取數據,然後複製該字符串在爲結構和'名稱'成員分配內存之後。換句話說,我將不得不遍歷任何指針,寫入數據,然後以相同的順序讀取數據。
編輯:丹和其他人是正確的。我已經看過了輸出文件與XXD:
0000000: 1600 0000 0000 0000 30a0 d900 0000 0000 ........0.......
如果我打印出「名」在寫之前包含地址和看完後是相同的(0xd9a030),從XXD輸出相匹配。
+1您可以通過printof sizeof(struct Person)和/或通過查看writen文件來檢查。 fread()正在讀取一個指針(一個內存地址),這恰好與當前的'person-> name'一致。 – leonbloy 2011-12-31 02:39:11
唯一的保證是結構在相同的環境配置中具有相同的長度。它可能會改變你使用-m32,-m64,更改全局對齊參數等的時刻。 – 2011-12-31 05:03:37