Search code examples
cmallocfree

free linked list that is inside a struct


I have an ordinateur of type ordi

typedef struct ordi
{
    int numeroOrdi;
    char *nomOrdi;
    int CapaciteDisque;
    lst_logi LogicielsInstalles;
} ordi;

this ordinateur has a doubly linked list LogicielsInstalles of type lst_logi

typedef struct lst_logi
{
    log *logiciel;
    struct lst_logi *next;
    struct lst_logi *prev;
} lst_logi;

I made a function FormaterOrdinateur to delete all "Logiciels"(Software in french)
In other word free the linked list LogicielsInstalles.

void FormaterOridinateur(ordi *ordinateur)
{
    lst_logi *head = &ordinateur->LogicielsInstalles;
    lst_logi *tmp;

    // printf("curr: %s\n", head->logiciel->designation);
    // printf("curr->next: %s\n", (head->next)->logiciel->designation);
    // these two line to make sure the node and node->next exit 
    while (head)
    {
       tmp = head;
       head = head->next;
       free(tmp);
    }
    ordinateur = NULL;
}

but this function gives me seg fault
more details with gdb:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7e244c9 in arena_for_chunk (ptr=0x7fffffffe051) at ./malloc/arena.c:156
156     ./malloc/arena.c: No such file or directory.

when I searched about arena_for_chunk error I found out that it means memory doesn't exist or can't be freed
I'm sure the node I'm trying to free exists so it just refuses to be freed.
any explanation for that. And how can I fix it.
Thanks in advance ;)


Solution

  • In the struct ordi, LogicielsInstalles should be a pointer, not a structure to account for computers with no installed software, and avoid an invalid free on &ordinateur->LogicielsInstalles.

    Furthermore, your function FormaterOrdinateur does not reset the pointer LogicielsInstalles after freeing the list. It instead sets ordinateur = NULL, which has no effect as ordinateur is just a local argument value.

    This may cause invalid access later or a double free.

    Here is a modified version:

    typedef struct lst_logi {
        log *logiciel;
        struct lst_logi *next;
        struct lst_logi *prev;
    } lst_logi;
    
    typedef struct ordi {
        int numeroOrdi;
        char *nomOrdi;
        int CapaciteDisque;
        lst_logi *LogicielsInstalles;
    } ordi;
    
    void FormaterOrdinateur(ordi *ordinateur) {
        lst_logi *node = ordinateur->LogicielsInstalles;
    
        while (node) {
            lst_logi *next = node->next;
            // free the log structure pointed to by node->logiciel
            free(node->logiciel);
            // free the node structure
            free(node);
            node = next;
        }
        ordinateur->LogicielsInstalles = NULL;
    }