【问题标题】:C Memory leaks to free for a Linked ListC 内存泄漏以释放链表
【发布时间】:2022-01-21 05:44:06
【问题描述】:

当我使用 valgrind 时,我的 ma​​in.c 中有内存泄漏和错误(错误在另一个测试文件中)。 (最后画面) 另外,我必须在 list.c 中的函数 list_destroy 中释放 only
看看这个:

编辑:感谢@kirjosieppo,我在下面的 create_cell 函数中删除了一个 malloc!现在:valgrind_updated

cell.c

// cell_s has gpointer ptr_value and struct cell_s *next
cell_t* create_cell(gpointer v) {
    cell_t *c = malloc(sizeof(cell_t));
    c->next = NULL;
    c->ptr_value = v;

    return c;
}

void destroy_int(gpointer data) {
    free((int *) data);
}

list.c

// list_s has cell_t *head and int size
list_t* list_create() {
    list_t *l = malloc(sizeof(list_t));

    l->head = NULL;
    l->size = 0;

    return l;
}

void list_insert_in_head(list_t *l, gpointer element) {
// typedef cell_t* adr
    adr address_c = create_cell(element);

    address_c->next = l->head;
    l->head = address_c;

    ++l->size;
}

void list_insert_next(list_t *l, gpointer element, adr address) {
    adr address_c = create_cell(element);

    if (l->head == NULL) {
        liste_insert_in_head(l, element);
    } else {
        address_c->next = address->next;
        address->next = address_c;
    }

    ++l->size;
} 

void list_remove_in_head(list_t *l) {
    if (l->head != NULL) {
        l->head = l->head->next;
    }

    --l->size;
}

void list_remove_after(list_t *l, adr address) {
    if (l->head->next == NULL) {
        printf("Use list_remove_in_head function\n");
    } else if (address != NULL) {
        address->next = address->next->next;

        --l->size;
    }
}

// Here is the problem !
void list_destroy(list_t *l, list_gfree ft_destroy) {
    adr current = l->head;

    while(current != NULL) {
        adr tmp = current;

        current = current->next;
        
        ft_destroy(tmp->ptr_value);
        tmp->ptr_value = NULL;
        
        ft_destroy(tmp);
    }

    free(l);
}

ma​​in.c

int main(void) {
    list_t *l = list_create();

    int *ptr_int = (int *)malloc(sizeof(int));
    *ptr_int = 4;
    list_insert_in_head(l, ptr_int);
    printf("Size : %d\n", l->size);

    int *ptr_int_2 = (int *)malloc(sizeof(int));
    *ptr_int_2 = 7;
    list_insert_in_head(l, ptr_int_2);
    printf("Size : %d\n", l->size);

    int *ptr_int_3 = (int *)malloc(sizeof(int));
    *ptr_int_3 = 100;
    list_insert_next(l, ptr_int_3, l->head);
    printf("Size : %d\n", l->size);

    list_remove_in_head(l);
    printf("Size : %d\n", l->size);

    list_remove_next(l, l->head);
    printf("Size : %d\n", l->size);

    list_remove_next(l, l->size);
    printf("Size : %d\n", l->size);

    list_destroy(l, destroy_int);
}

valgrind
在我的插入中检测到内存泄漏。 valgrind

感谢您帮助我解决了 0 个内存泄漏和 0 个错误! :-)

【问题讨论】:

  • 作为解决问题的策略,遇到这种情况的第一件事就是隔离问题。如果仅创建和销毁列表,请检查是否发生泄漏。然后添加一个节点并测试。在头部、中间和尾部测试插入。在头部、中间和尾部测试删除。如果你已经这样做了,然后想出了作为最小可重复示例编写的程序,那么你应该解释这就是你所做的。但我不认为你还在那里,因为隔离问题的过程将准确地确定是哪个函数造成了问题。
  • @paddy 我已经这样做了,当我插入一个节点(在头部和特定节点之后)时会发生泄漏。我不知道为什么。 :/ 当我创建一个没有节点的列表时,没关系。最后我说:“在我的插入中检测到内存泄漏。”
  • 您拨打list_insert_in_head 两次(ptr_intptr_int_2)。这是故意的吗?
  • @kirjosieppo 我插入了头部 4 (ptr_int) 并插入了头部 7 (ptr_int_2)。所以,是的,我为这个测试文件调用了两次 list_insert_in_head :)
  • 抱歉,我明白了。

标签: c memory-leaks linked-list valgrind free


【解决方案1】:

我还没有测试这是否真的是(唯一的)问题,但是有这样的代码:

create_cell(gpointer v) {
// clip
    c->ptr_value = malloc(sizeof(int));
    c->ptr_value = v;

进行分配,然后丢弃指针。

让我们继续!还有什么可以发现的?

list_remove_in_head() 中,单元格l->head 被覆盖而不被释放。可以这样修复:

void list_remove_in_head(list_t *l) {
    if (l->head != NULL) {
        void *tmp = l->head->next;
        free(l->head->ptr_value);
        free(l->head);
        l->head = tmp;
    }

    --l->size;
}

这同样适用于list_remove_after(),但我想你可以自己解决。 :)

【讨论】:

  • 我不太明白这2行create_cell函数的问题。我不认为这个功能有问题。我认为问题出在 list_destroy 函数 //clip comment 是什么?
  • 好吧,clip 的意思就是“省略了一些行”。然而,这里我们调用了malloc,它的指针会立即被重写丢弃。 (原谅我的英语,我很累)
  • 我得到了它的剪辑。啊我的main.c文件的多个malloc是问题,没必要吧? :-)
  • 是的,实际进入列表的分配是在main 中进行的。 create_cell 中的额外 malloc 是多余的。
  • @kirjoseppo 好的,我明白了!谢谢你帮助我。我绿色检查你的答案。 :)
猜你喜欢
  • 2014-09-19
  • 2012-06-08
  • 2014-08-26
  • 1970-01-01
  • 1970-01-01
  • 2011-01-27
  • 2010-12-04
  • 2023-03-23
  • 2012-12-13
相关资源
最近更新 更多