在C中实现双链表实现的pop方法,我是否需要使用free

丹尼尔·科比(Daniel Kobe)

作为C语言的初学者,我不确定何时应该使用free。我正在研究一种pop方法,该方法从列表的末尾删除一个元素。它还应返回已删除元素的值。

这是我ListListNode结构

typedef struct ListNode {
    struct ListNode *next;
    struct ListNode *prev;
    void *value;
} ListNode;

typedef struct List {
    int count;
    ListNode *first;
    ListNode *last;
} List;

这是我remove_from_back函数的代码

void *remove_from_back(List *list)
{
    void *result = NULL;

    if (list->last == NULL) return result;

    result = list->last->value;
    if (list->last->value == list->first->value) {
        list->last = list->first = NULL;    
    } else {
        list->last = list->last->prev;
        list->last->next = NULL;        
    }   
    return result;
}

add_to_back函数,为节点创建内存

void add_to_back(List *list, void *value)
{  
    ListNode *node = calloc(1, sizeof(ListNode));
    node->value = value;

    if (list->first == NULL) {
        list->first = node;
        list->last = node;
    } else {
        list->last->next = node;
        node->prev = list->last;
        list->last = node;
    }

    list->count++;
}
乔纳森·勒夫勒(Jonathan Leffler)

由于您的add_to_back()函数为该节点分配了内存,因此该remove_from_back()函数应删除该节点的内存。但是,它不应释放该节点指向的数据。因此:

void *remove_from_back(List *list)
{
    void *result = NULL;

    if (list->last == NULL) return result;

    ListNode *dead = list->last;            // Added
    result = list->last->value;
    if (list->last->value == list->first->value) {
        list->last = list->first = NULL;    
    } else {
        list->last = list->last->prev;
        list->last->next = NULL;        
    } 
    free(dead);                             // Added
    return result;
}

我只添加了两行。我没有更改任何中间行,因此,如果原始代码中有错误,那么这些错误也将包含在修订的代码中。但是添加的行可以防止在将数据添加到列表时分配的节点泄漏。

分配内存时,您需要知道相应的free()位置。如果您不知道,则需要决定如何释放它并实施释放机制。有时,您可以做出无所谓的决定-该程序无论如何都将退出。但是可重用的代码很少能证明这一假设。这就像打开和关闭文件一样-您可以忽略关闭文件,但是最终您会遇到打开文件过多的问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章