C 为什么我可以分配一个局部变量和fread给它,但是如果我试图在结构中分配一个指针并读取它,那么segfault呢?

C 为什么我可以分配一个局部变量和fread给它,但是如果我试图在结构中分配一个指针并读取它,那么segfault呢?,c,pointers,struct,C,Pointers,Struct,我正在玩一个小C程序来复习。我有以下结构 struct Address { int id; int set; char *name; char *email; }; 我正试图读入一些数据。这项工作: size_t len = 256 * sizeof(char); struct Address *thisAddress = malloc(sizeof(struct Address)); char *name = malloc(len); char *email

我正在玩一个小C程序来复习。我有以下结构

struct Address {
    int id;
    int set;
    char *name;
    char *email;
};
我正试图读入一些数据。这项工作:

size_t len = 256 * sizeof(char);

struct Address *thisAddress = malloc(sizeof(struct Address));
char *name = malloc(len);
char *email = malloc(len);

rc = fread(thisAddress, sizeof(struct Address), 1, conn->file);
if(rc != 1) die("Failed to load address.", conn);

rc = fread(name, len, 1, conn->file);
if(rc != 1) die("Failed to load name.", conn);

rc = fread(email, len, 1, conn->file);
if(rc != 1) die("Failed to load email.", conn);

thisAddress->name = name;
thisAddress->email = email;
conn->db->rows[i] = thisAddress;
但这是错误的:

size_t len = 256 * sizeof(char);
struct Address *thisAddress = malloc(sizeof(struct Address));
thisAddress->name = malloc(len);
thisAddress->email = malloc(len);

rc = fread(thisAddress, sizeof(struct Address), 1, conn->file);
if(rc != 1) die("Failed to load address.", conn);

rc = fread(thisAddress->name, len, 1, conn->file);
if(rc != 1) die("Failed to load name.", conn);

rc = fread(thisAddress->email, len, 1, conn->file);
if(rc != 1) die("Failed to load email.", conn);

conn->db->rows[i] = thisAddress;
如果您不能立即看到它,在第一个示例中,我将对名称进行malloc'并编辑变量,从文件中读取这些变量,然后将它们分配给struct Address上的名称和电子邮件指针。在第二个例子中,我尝试在struct Address上分配指针,并直接读取它们

为什么这两者会有所不同?任何见解都是有帮助的,谢谢

首先要做的是

thisAddress->name = malloc(len);
thisAddress->email = malloc(len);
那你呢

rc = fread(thisAddress, sizeof(struct Address), 1, conn->file);
该结构的读取将覆盖您以前设置的指针。因此,用于从文件中读取姓名和电子邮件地址文本的指针不是您分配的指针,而是您从文件中读取的指针,它们不太可能指向任何有效内存,从而导致未定义的行为


如果您更改第一个结构的读取顺序和分配顺序,它应该可以工作。

malloc(strlen)
?什么?您是在尝试使用strlen函数,还是使用同名变量对函数进行阴影处理?那个变量的值是多少?请尝试创建一个并向我们展示。@JoachimPileborg我不确定我是否理解建议对问题进行更改,然后继续回答。其他经验不足的人迟早会发现您的问题,没有看到一个好的MCVE,尤其是看到一个常用函数用作变量会让他们非常困惑。这个网站不仅能为你当前的问题提供答案,而且还能帮助其他在将来遇到类似(或相同)问题的人。嗨,伙计们,很抱歉。在块外部设置的变量名选择不当,因此错过了复制粘贴。是我的错。我进行了更新以提高可读性。我担心这一点,但阅读手册页时说“函数fread()从流指向的流中读取nitems对象,每个大小字节长,并将它们存储在ptr给定的位置。”这使我相信正在读取的缓冲区应该复制到输入ptr指向的内存地址。如果是这种情况,那么我不明白为什么指针本身会被覆盖。@Herm
sizeof(struct Address)
是结构的完整大小,包括
name
email
成员。因此,当您告诉
fread
读取
sizeof(struct Address)
字节的一个元素时,它会这样做,并将读取的所有字节写入
thisAddress
给出的指针。文件中的内容很可能不是当前进程的非常有效的指针,在使用指针时会导致未定义的行为。解决方案是,就像我说的,在你阅读结构之后,将分配移动到。啊!!!我现在完全明白了!这确实有助于澄清!我以前错误地看了你原来的评论。非常感谢。