0

I'm creating generic linked list. Data to the list is loading from the .txt file (loadClients function). The problem is, when I push second element to the list (push_back function), malloc() doesn't work sometimes and I have an error 0xC0000005. For example, I run the program 10 times and it works well but for the 11th time I have an error. I can't even check what malloc() returns.

Here is the client struct:

typedef struct client
{
    int card_no;
    char last_name[30];
    char first_name[30];
    int phone_no;
    char email[60];
    char login[18];
    char password[20];
    bool admin;
}client_struct;

Here is the generic list:

typedef struct List
{
    void *data;
    struct List *next;
}List;

Here is the push_back function:

void push_back(List **head,void *data,size_t size)
{
    if(*head==NULL)
    {
        *head = (List *)malloc(sizeof(List));
        (*head)->data = malloc(size);
        (*head)->data = data;
        (*head)->next = NULL;
    }else
    {
        List *current = *head;
        while(current->next != NULL)
            current = current->next;
        printf("PUSH BACK1!\n");
        current->next = (List *)malloc(sizeof(List)); //HERE IS THE PROBLEM
        printf("PUSH BACK2!\n");
        current->next->data = malloc(size);
        current->next->data = data;
        current->next->next = NULL;
    }
}

Here is the loadClients function. This function returns the pointer to the created list.

List *loadClients()
{
    List *client_head = NULL;
    FILE *users = fopen("users.txt","r");
    if(users == NULL)
        return NULL;
    while(!feof(users))
    {
        client_struct *cl = malloc(sizeof(client_struct));
        memset(cl,0,sizeof(client_struct));
        char tab[200];
        memset(tab,0,200);
        fgets(tab,200,users);
        sscanf(tab,"%d %s %s %d %s %s %s %d",
    &cl->card_no,cl->last_name,cl->first_name,&cl->phone_no,
    cl->email,cl->login,cl->password,&cl->admin);
        printf("ADD\n");
        if(cl->card_no != 0)
            push_back(&client_head,(client_struct *)cl,sizeof(client_struct));
    }
    fclose(users);
    return client_head;
}

How can I fix this problem?

Damian
  • 43
  • 4
  • 3
    Not your main problem, but please read [Why is “while (!feof(file))” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feoffile-always-wrong). – unwind Apr 08 '19 at 11:34
  • 3
    `(*head)->data = malloc(size);` `(*head)->data = data;` looks wrong and is a memory leak. I think you intended to copy the data. For that, use `(*head)->data = malloc(size);` `memcpy((*head)->data, data, size);`. Similarly for the other branch that uses `current->next->data`. – Ian Abbott Apr 08 '19 at 11:37
  • Regarding my earlier comment, since `push_back` is being called with a pointer to a `malloc`d block anyway (from the `cl` variable in `loadClients()`), perhaps you do not need to copy the data and can just get rid of the `(*head)->data = malloc(size);` and `current->next->data = `malloc(size);` lines, and keep the `(*head)->data = data;` and `current->next->data = data;` lines. Then there is no need to pass `size` to the `push_back` function unless you want to store the size in additional member of `List`. – Ian Abbott Apr 08 '19 at 11:52
  • Thank you for pointing out, I changed to memcpy() and it still worked bad, but I also changed loadClients() function inside the while loop. This time I used `client_struct cl = EmptyStruct;` and `push_back(&client_head,(client_struct *)&cl,sizeof(client_struct));` and it works well (EmptyStruct is `static const client_struct EmptyStruct;`). Thank you very much for help! – Damian Apr 08 '19 at 11:58
  • `current->next` This will be always NULL after `while(current->next != NULL) {...}`. Result will be `NULL = malloc`, but wait this is illegal. – Igor Galczak Apr 08 '19 at 12:10

1 Answers1

-1

Compile with debugging info (-g flag):

gcc -g code.c

Then run it through valgrind:

valgrind ./a.out

Then valgrind will give you lots of useful info about what it is that goes wrong, on what line in the code and so on.

Elias
  • 913
  • 6
  • 22