6

I have an array of structs I would like to write to a binary file. I have a write.c program and a read.c program. The write.c program seems to be working properly but when I run the read.c program I get a segmentation fault. I'm new to C so It would be great if someone could look over my code for any obvious errors. I promise it's not too long :)

write.c:

#include <stdlib.h>
#include <stdio.h>

struct Person 
{
    char f_name[256];
    char l_name[256];
    int age;
};

int main(int argc, char* argv[])
{
    struct Person* people;
    int people_count;

    printf("How many people would you like to create: ");
    scanf("%i", &people_count);
    people = malloc(sizeof(struct Person) * people_count);  

    int n;
    for (n = 0; n < people_count; n++)
    {
        printf("Person %i's First Name: ", n);
        scanf("%s", people[n].f_name);

        printf("Person %i's Last Name: ", n);
        scanf("%s", people[n].l_name);

        printf("Person %i's Age: ", n);
        scanf("%i", &people[n].age);
    }

    FILE* data;
    if ( (data = fopen("data.bin", "wb")) == NULL )
    {
        printf("Error opening file\n");
        return 1;   
    }

    fwrite(people, sizeof(struct Person) * people_count, 1, data);
    fclose(data);

    return 0;
}

read.c:

#include <stdlib.h>
#include <stdio.h>

struct Person 
{
    char f_name[256];
    char l_name[256];
    int age;
};

int main(int argc, char* argv[])
{
    FILE* data;
    if ((data = fopen("data.bin", "rb")) == NULL)
    {
        printf("Error opening file\n");
        return 1;
    }

    struct Person* people;

    fread(people, sizeof(struct Person) * 1/* Just read one person */, 1, data);
    printf("%s\n", people[0].f_name);

    fclose(data);

    return 0;
}

Thanks for the help!

1
  • How many times a day does this question get asked? There should be a 'C' FAQ that will allow us to point to the answer rather than spending the time writing all this down time after time after time...... Commented Dec 6, 2010 at 16:57

4 Answers 4

6
struct Person* people;

This allocates just a pointer to struct, but you don't have any allocated space for actual struct contents. Either use malloc similarly to your write program, or try something like:

struct Person people;
fread(&people, sizeof(people), 1, data);
Sign up to request clarification or add additional context in comments.

Comments

4

You need to allocate memory for the person first. Change: struct Person* people; into struct Person* people = malloc(sizeof(struct Person));. And don't forget to free your memory at the end: free(people);.

4 Comments

Can you explain when the (struct Person*) means before the malloc(sizeof(struct Person))? Is that a cast?
@jjacquay712 Yes it is. I just like to not relay too much on default compiler options.
Please do not cast the result from malloc. It is standard and well-defined C behaviour, and idiomatic C to leave it out. You are guaranteed to get an implicit cast. If you do cast, the compiler is no longer able to diagnose the error if you forget to #include <stdlib.h>.
@Karl Knechtel Thanks, for pointing this out. Edited and removed casting.
2

You either need to malloc memory into the pointer variable people before you do the fread, or (easier) just read directly into a local variable:

struct Person people;

fread(&people, sizeof(struct Person) * 1/* Just read one person */, 1, data);

Comments

2

You need to allocate space for the data you are reading in:

people = malloc(sizeof(*people)*numPeople);

1 Comment

This seems more extensible once OP decides to read > 1 element. Could loop on a single local variable instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.