首页 > 解决方案 > 如何正确调用 free()?

问题描述

请阅读整篇文章,因为它包含非常重要的小细节。

正如 C 所知道的,我们应该处理malloc失败的事件,对于这种情况,我创建了一个名为的函数destroyList(),它的工作是获取一个指向Node并一个一个销毁它的指针。但是我的函数没有被正确调用......

我试图用 ptr 调用它,merged_out并且*merged_out(最后一个是社区成员的建议)但似乎没有任何效果。

这是为什么?该函数有时会接收NULL、 空列表或一些随机值。

有人可以帮我解决这个问题并让我了解发生了什么吗?

typedef struct node_t {
    int x;
    struct node_t *next;
} *Node;

void destroyList(Node ptr) {
    while (ptr) {
        Node toDelete = ptr;
        ptr = ptr->next;
        free(toDelete);
    }
}

主功能:

ErrorCode mergeSortedLists(Node list1, Node list2, Node *merged_out) {
    if (!list1 || !list2) {
        return EMPTY_LIST;
    }
    if (!isListSorted(list1) || !isListSorted(list2)) {
        return UNSORTED_LIST;
    }
    if (!merged_out) {
        return NULL_ARGUMENT;
    }
    Node ptr = NULL;
    int total_len = getListLength(list1) + getListLength(list2);
    for (int i = 0; i < total_len; i++) {
        int min = getMin(&list1, &list2);
        ptr = malloc(sizeof(*ptr));
        *merged_out = ptr;
        if (!ptr) {
            destroyList(*merged_out);
            *merged_out = NULL;
            return MEMORY_ERROR;
        }
        ptr->x = min;
        ptr->next = NULL;
        merged_out = &ptr->next;
    }
    return SUCCESS;
}

这就是函数的调用方式:

Node merged_actual = NULL;
ErrorCode merge_status = mergeSortedLists(list1, list2, &merged_actual);

注意getMin()获取最小值并将具有该最小值的列表的指针前进到下一个节点。

标签: cmemory-leaksmallocfreec99

解决方案


在这些if检查之后开始。

    Node ptr=NULL,last;
    /* find out current tail of the list */
    if (*merged_out!=NULL){
        last=*merged_out;
        while (last->next!=NULL){
            last=last->next;
        }
    }
    int total_len = getListLength(list1) + getListLength(list2);
    for (int i = 0; i < total_len; i++)
    {
        int min = getMin(&list1, &list2);
        ptr = malloc(sizeof(*ptr));
        if (!ptr)
        {
            destroyList(*merged_out);
            *merged_out=NULL;
            return MEMORY_ERROR;
        }
        ptr->x = min;
        ptr->next = NULL;
        /* link ptr onto the list */
        if (*merged_out==NULL){
            /* if the list is empty, make ptr the head of the list */
            *merged_out=ptr;
            last=*merged_out;
        }
        else{
            last->next = ptr;
            last = ptr;
        }
    }

请尽量不要复制粘贴这段代码。它可能正确也可能不正确,但请尝试理解它的作用:每次调用函数时都进行迭代,last以指向列表的最后一个元素。因此merged_out可以一直指向头部。


推荐阅读