0

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?

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I can't change that pointers because I cannot know the lengths so I'm thinking of storing every raw data to a file and then create the structure again with this data values as I'm doing the first time when the file doesn't exists.

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.