Reputation: 339
I have 2 files that are creator.c and 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 file create a binary file called save.bin and push the person struct data as binary, reader.c read from that file and print the name of the person but this code getting segmentation fault, what is the point that i missed out?
Upvotes: 0
Views: 45
Reputation: 67195
This code:
fread(person1,sizeof(struct Person),1,fp);
... reads a Person
structure from the file.
And this code:
printf("%s\n",person1->name );
.. attempts to access the memory that Person.name
points to.
But what does it point to? name
contains a memory address that you read from the file, but no memory has been allocated for the name. You are reading the memory at that address but that address is no longer a valid memory address. And you get a segmentation fault when you attempt to access invalid memory.
There are several ways to deal with this but the easiest is to store the name in the same block of memory. You can do that like this:
#define MAX_NAME 80
struct Person{
char name[MAX_NAME + 1];
int numb;
char *kind;
};
Now, reading the person also reads the name. You'll also need to do the same thing with kind
or you'll have the same problem there.
Upvotes: 1
Reputation: 25286
write
does not write the values of the things pointed to. It will write the pointers. When you read, you read the pointers, but they are invalid.
Either declare name
and kind
as fixed-sized arrays, or write their values separately and then don't forget to malloc new memory before you read them.
EDIT: it is better to first write the length of the name and then read exactly that length, because more records can follow.
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 );
}
Upvotes: 3