我有2个文件,分别是creator.c和reader.c
creator.c:
#include <stdio.h>
#include <string.h>
struct Person{
char *name;
int numb;
char *kind;
};
int main() {
struct Person *per1=malloc(sizeof(struct Person));
struct Person *per2=malloc(sizeof(struct Person));
struct Person *per3=malloc(sizeof(struct Person));
struct Person *per4=malloc(sizeof(struct Person));
struct Person *per5=malloc(sizeof(struct Person));
struct Person *per6=malloc(sizeof(struct Person));
char per1_name[]="a1";
char per2_name[]="b1";
char per3_name[]="c1";
char per4_name[]="d1";
char per5_name[]="e1";
char per6_name[]="f1";
per1->name=malloc(strlen(per1_name)+1);
per2->name=malloc(strlen(per2_name)+1);
per3->name=malloc(strlen(per3_name)+1);
per4->name=malloc(strlen(per4_name)+1);
per5->name=malloc(strlen(per5_name)+1);
per6->name=malloc(strlen(per6_name)+1);
strcpy(per1->name,per1_name);
strcpy(per2->name,per2_name);
strcpy(per3->name,per3_name);
strcpy(per4->name,per4_name);
strcpy(per5->name,per5_name);
strcpy(per6->name,per6_name);
per1->numb=1;
per2->numb=2;
per3->numb=3;
per4->numb=4;
per5->numb=5;
per6->numb=6;
char per1_kind[]="x";
char per2_kind[]="y";
char per3_kind[]="z";
char per4_kind[]="q";
char per5_kind[]="w";
char per6_kind[]="e";
per1->kind=malloc(strlen(per1_kind)+1);
per2->kind=malloc(strlen(per2_kind)+1);
per3->kind=malloc(strlen(per3_kind)+1);
per4->kind=malloc(strlen(per4_kind)+1);
per5->kind=malloc(strlen(per5_kind)+1);
per6->kind=malloc(strlen(per6_kind)+1);
strcpy(per1->kind,per1_kind);
strcpy(per2->kind,per2_kind);
strcpy(per3->kind,per3_kind);
strcpy(per4->kind,per4_kind);
strcpy(per5->kind,per5_kind);
strcpy(per6->kind,per6_kind);
FILE *write_ptr;
write_ptr = fopen("save.bin","wb");
fwrite(per1,sizeof(struct Person),1,write_ptr);
fwrite(per2,sizeof(struct Person),1,write_ptr);
fwrite(per3,sizeof(struct Person),1,write_ptr);
fwrite(per4,sizeof(struct Person),1,write_ptr);
fwrite(per5,sizeof(struct Person),1,write_ptr);
fwrite(per6,sizeof(struct Person),1,write_ptr);
return 0;
}
reader.c
#include <stdio.h>
struct Person{
char *name;
int numb;
char *kind;
};
int main(){
FILE *fp=fopen("./save.bin","rb");
struct Person *person1=malloc(sizeof(struct Person));
fread(person1,sizeof(struct Person),1,fp);
printf("%s\n",person1->name );
}
creator.c文件创建一个名为save.bin的二进制文件,并将person结构数据推送为二进制文件, reader.c从该文件读取并打印此人的名字,但是此代码出现了段错误,我错过了什么呢?
答案 0 :(得分:3)
write
不会写所指事物的值。它将写入指针。读取时,您会读取指针,但是它们无效。
要么将name
和kind
声明为固定大小的数组,要么分别写入它们的值,然后在读取它们之前不要忘记分配新的内存。
编辑:最好先写下名称的长度,然后准确读取该长度,因为可以跟随更多的记录。
int main() {
struct Person *per1=malloc(sizeof(struct Person));
per1->name=malloc(strlen("hello")+1);
strcpy(per1->name,"hello");
FILE *write_ptr;
write_ptr = fopen("save.bin","wb");
fwrite(per1,sizeof(struct Person),1,write_ptr);
int len= strlen(per1->name);
fwrite(&len,sizeof(int), 1, write_ptr; // first write the length
fwrite(per1->name,len,1,write_ptr); // then write those bytes
fclose(write_ptr); // don't forget!
return(0);
}
// reader
int main(){
FILE *fp=fopen("./save.bin","rb");
struct Person *person1=malloc(sizeof(struct Person));
fread(person1,sizeof(struct Person),1,fp);
int len;
fread(&len,sizeof(int),1,fp); // now read the length
person1->name=malloc(len+1); // allocate memory for it,
fread(person1->name,len,1,fp); // read it
person1->name[len]= '\0'; // and terminate it
printf("%s\n",person1->name );
}
答案 1 :(得分:1)
此代码:
fread(person1,sizeof(struct Person),1,fp);
...从文件中读取Person
结构。
这段代码:
printf("%s\n",person1->name );
..尝试访问Person.name
指向的内存。
但是它指向什么呢? name
包含您从文件中读取的内存地址,但尚未为该名称分配内存。您正在读取该地址处的内存,但是该地址不再是有效的内存地址。当您尝试访问无效的内存时,您会遇到分段错误。
有几种处理方法,但是最简单的方法是将名称存储在同一块内存中。您可以这样做:
#define MAX_NAME 80
struct Person{
char name[MAX_NAME + 1];
int numb;
char *kind;
};
现在,读人也读名字。您还需要对kind
做同样的事情,否则您将遇到同样的问题。