Roger Fernandez Guri
Roger Fernandez Guri

Reputation: 988

Read struct from binary file using read

I'm doing a simple operation over a complex client/server (multi chating rooms) program in C.

I've a linkedlist structure called node

struct node
{
    char *user;
    char *passwd;
    int id;
    int connected;
    struct node *next;
};

And another structure called room

struct room
{
    char *name;
    int capacity;
    int room_id;
    int admin_id;
    struct room *next;
    struct node *users;
};

I declare this as a global variable:

struct room *rooms = NULL;

I've already protected it with mutex and semaphores.

So I just want to write this structure when the server ends and then load it later when the server starts again. The logic of doing that resides in two files, server.c and *server_utils.c* as I'm showing below:

server.c:

int main (void)
{
    [...]
    struct stat st;
    [...]
    stat ("rooms.bin", &st);
    if (st.st_size > 0)
    {
        // Load rooms
        load_rooms ();
    }
    else
    {
        [...]
    }
    [...]
    exit (EXIT_SUCCESS);
}

*server_utils.c*:

[...]

void load_rooms (void)
{
    int fd;
    if ((fd = open ("rooms.bin", O_RDONLY)) < 0)
    {
        perror ("open");
        exit (EXIT_FAILURE);
    }
    else
    {
        read (fd, &rooms, sizeof (rooms));
    }
}

void save_rooms (void)
{
    int fd;
    if ((fd = open ("rooms.bin", O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0)
    {
        perror ("open");
        exit (EXIT_FAILURE);
    }
    else
    {
        write (fd, &rooms, sizeof (rooms));
    }
}

[...]

The problem I found is that when I read the structure from the binary file with

read (fd, &rooms, sizeof (rooms));

And then I try to print the structure with

void rooms_linkedlist_print (struct room *head)
{
    struct room *curr = head;
    char str[1024];
    while (curr != NULL)
    {
        write (1, curr->name, strlen (curr->name));
        write (1, "\n", strlen ("\n"));
        bzero (str, 1024);
        sprintf (str, "%d\n", curr->capacity);
        write (1, str, strlen (str));
        bzero (str, 1024);
        sprintf (str, "%d\n", curr->room_id);
        write (1, str, strlen (str));
        bzero (str, 1024);
        sprintf (str, "%d\n", curr->admin_id);
        write (1, str, strlen (str));
        curr = curr->next;
    }
}

I get a segmentation fault (core dumped). Any ideas on what I'm doing wrong?

Upvotes: 0

Views: 176

Answers (1)

Peter de Rivaz
Peter de Rivaz

Reputation: 33509

Your room struct has pointers inside it.

These pointers will no longer necessarily point to allocated memory when you reload the data, causing a segmentation fault.

You could fix this by changing from using pointers into using indices into the rooms array.

Upvotes: 2

Related Questions