如何在 C 中释放链表,为什么在不释放列表的情况下它运行良好?

How do I free a linked list in C and why does it work well without freeing the list?

提问人:Nouanna 提问时间:2/3/2023 最后编辑:Nouanna 更新时间:2/4/2023 访问量:72

问:

typedef struct Element Element;
struct Element{
    char chaine[2048];
    struct Element *next;
};

typedef struct Liste Liste;
struct Liste{
    int taille;
    struct Element *premier;
};

Liste listeinit(void){
    Liste *L = malloc(sizeof(Liste));
    L->taille = 0;
    L->premier = NULL;
    return *L;
}


void inseretete(Liste *L,char *x){
    Element *ele = malloc(sizeof(Element));
    if (ele == NULL){
        printf("Erreur en attribuant la memoire");
        return;
    }
    int cpt = 0;
    while (x[cpt]!='\0'){
        ele->chaine[cpt]=x[cpt];
        cpt ++;
    }
    ele->chaine[cpt]='\0';
    ele->next = L->premier;
    L->premier = ele;
    L->taille ++;
}


void freeliste(Liste *L){
    while(L->premier != NULL){
      Element *a = L->premier;
      L->premier = L->premier->next;
      free(a);
    }
    free(L);
}

我正在尝试释放链表,当我删除 free(L) 行时它有点工作,但当它在那里时,它会打印“double free or corrupt”。我该如何解决这个问题?

我们尝试删除并添加它。

C list malloc valgrind 免费

评论

0赞 MSalters 2/3/2023
这是一个不完整的例子。缺少,它可能没有使用 .只有在堆上分配时才能使用。createlistemallocfree(L)L
0赞 Barmar 2/3/2023
您可能正在释放调用方中的对象。请发布一个最小的可重现示例Liste
0赞 Ivan Venkov 2/3/2023
你没有错过一个吗?}struct Element *premier;
0赞 Nouanna 2/4/2023
@MSalters我编辑了我的帖子。但我还是不明白,对不起......
0赞 Mark Benningfield 2/4/2023
在函数中,将指针泄漏到已分配的内存;你不是在返回指针,而是在返回内存指向的结构的副本。listeinit

答:

0赞 John Bollinger 2/4/2023 #1

这。。。

Liste listeinit(void){
    Liste *L = malloc(sizeof(Liste));
    L->taille = 0;
    L->premier = NULL;
    return *L;
}

...是错误的。您正在为 动态分配内存,但随后按值返回该副本,并泄漏分配的内存。此外,如果将副本记录在本身不是动态分配的空间中,则无法通过 释放该空间。Listefree()

据推测,您希望返回指针而不是已分配空间的副本:

Liste *listeinit(void) {
    Liste *L = malloc(sizeof(Liste));
    L->taille = 0;
    L->premier = NULL;
    return L;
}

当然,调用方需要进行调整以匹配。准备就绪后,将指针传递给 。freeliste()


或者,您可以提供一个函数来初始化 不为其分配内存。然后,这将与一个函数配对,用于释放节点,该节点不会尝试释放自身。例如ListeListe

void listeinit(Liste *L){
    L->taille = 0;
    L->premier = NULL;
}

void freelistenodes(Liste *L) {
    while (L->premier != NULL) {
      Element *a = L->premier;
      L->premier = L->premier->next;
      free(a);
    }
}

void useliste() {
    Liste my_liste;

    listeinit(&my_liste);

    // do something with my_liste ...

    freelistenodes(&my_liste);
}