结构内的自由链表

free linked list that is inside a struct

我有一个 ordinateur 类型 ordi

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

这个 ordinateur 有一个类型为 lst_logi

的双向链表 LogicielsInstalles
typedef struct lst_logi
{
    log *logiciel;
    struct lst_logi *next;
    struct lst_logi *prev;
} lst_logi;

我创建了一个函数FormaterOrdinateur来删除所有“Logiciels”(法语软件)
换句话说,释放链表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;
}

但是这个函数给我段错误
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.

当我搜索 arena_for_chunk 错误时,我发现这意味着内存不存在或无法释放
我确定我要释放的节点存在,所以它只是拒绝被释放。
任何解释。我该如何解决它。
提前致谢 ;)

struct ordi中,LogicielsInstalles应该是一个指针,而不是一个结构来计算没有安装软件的计算机,避免&ordinateur->LogicielsInstalles上的无效free .

此外,您的函数 FormaterOrdinateur 在释放列表后不会重置指针 LogicielsInstalles。它改为设置 ordinateur = NULL,这没有任何效果,因为 ordinateur 只是一个局部参数值。

这可能会导致以后访问无效或双重释放。

这是修改后的版本:

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;
}