【问题标题】:Can't find memory leak in linked lists function "16 bytes in 1 blocks are definitely lost in loss record 1 of 1"在链表函数中找不到内存泄漏“1 个块中的 16 个字节肯定在丢失记录 1 of 1 中丢失”
【发布时间】:2021-03-17 16:18:51
【问题描述】:

我正在学习 C 并编写了一些函数来处理 C 中的链表。但是,我有内存泄漏(我猜是因为在第 28 和 29 行重新分配了 node* 列表)并且正在寻找一个解决方法。

我的代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
    int number;
    struct node *next;
}
node;

node *declare(int value);
int count(node *list);
node *lead(node *list, int value);
void trail(node *list, int value);
node *append(node *list, int value, int index);
node *fetch_node(node *list, int index);
int fetch(node *list, int index);
int *list_to_array(node *list);
node *array_to_list(int array[], int range);
void free_list(node *list);
node *delete(node *list, int index);
void print(node *list);

int main(void)
{
    node *list = declare(1);
    list = lead(list, -1);
    trail(list, 2);
    trail(list, 44);
    list = delete(list, 0);
    append(list, 232, 1);
    int *array = list_to_array(list);
    node *list_new = array_to_list(array, 4);
    printf("%d\n", fetch(list_new, 3));
    print(list);
    free_list(list);
    free_list(list_new);
    free(array);
}

node *declare(int value)
{
    node *n = malloc(sizeof(node));
    n->number = value;
    n->next = NULL;
    return n;
}

int count(node *list)
{
    node *tmp = list;
    int count = 1;
    while (tmp->next != NULL)
    {
        tmp = tmp->next;
        count++;
    }
    return count;
}

node *lead(node *list, int value)
{
    node *n = declare(value);
    node *tmp = list;
    n->next = tmp;
    return n;
}

void trail(node *list, int value)
{
    node *n = declare(value);
    node *tmp = list;
    while (tmp->next != NULL)
    {
        tmp = tmp->next;
    }
    tmp->next = n;
}

node *append(node *list, int value, int index)
{
    if (index == 0)
    {
        return lead(list, value);
    }
    else
    {
        int range = count(list);
        node *n = declare(value);
        node *prev = fetch_node(list, index - 1);
        node *follow = fetch_node(list, index);
        prev->next = n;
        n->next = follow;
        return list;
    }

}

node *fetch_node(node *list, int index)
{
    node *tmp = list;
    if (index < count(list))
    {
        for (int i = 0; i < index; i++)
        {
            tmp = tmp->next;
        }
    }
    else
    {
        fprintf(stderr, "VALUE IN FETCH OUT OF RANGE, RETURNING POINTER TO LIST\n");
    }
    return tmp;
}

int fetch(node *list, int index)
{
    node *fetched = fetch_node(list, index);
    return fetched->number;
}

node *delete(node *list, int index)
{
    if (index == 0)
    {
        node *follow = list->next;
        list = list->next;
    }
    else
    {
        node *fetched = fetch_node(list, index);
        node *prev, *follow;
        if (index > 0)
        {
            prev = fetch_node(list, index - 1);
        }
        else
        {
            prev = list;
        }
        int range = count(list);
        if (index != range - 1 && index < range)
        {
            follow = fetch_node(list, index + 1);
        }
        else
        {
            follow = NULL;
        }
        prev->next = follow;
    }
    return list;
}

int *list_to_array(node *list)
{
    int range = count(list);
    int *array = malloc(sizeof(int) * range);
    for (int i = 0; i < range; i++)
    {
        array[i] = fetch(list, i);
    }
    return array;
}

node *array_to_list(int array[], int range)
{
    node *list = declare(array[0]);
    for (int i = 1; i < range; i++)
    {
        trail(list, array[i]);
    }
    return list;
}

void free_list(node *list)
{
    int range = count(list);
    node *tmp = list;
    node *del;
    for (int i = 0; i < range; i++)
    {
        del = tmp;
        tmp = tmp->next;
        free(del);
    }
}

void print(node *list)
{
    int range = count(list);
    printf("[");
    for (int i = 0; i < range; i++)
    {
        int value = fetch(list, i);
        printf("%d", value);
        if (i != range - 1)
        {
            printf(", ");
        }
    }
    printf("]\n");
}

这是 Valgrind 的输出:

==18184== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==18184==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18184==    by 0x4007C4: declare (linked_lists.c:45)
==18184==    by 0x400806: lead (linked_lists.c:65)
==18184==    by 0x4006F3: main (linked_lists.c:29)

有什么想法吗?

【问题讨论】:

    标签: arrays c memory-leaks linked-list


    【解决方案1】:

    您的 delete 函数正在造成内存泄漏,因为它没有释放已删除的节点。

    添加代码以释放它。

    node *delete(node *list, int index)
    {
        if (index == 0)
        {
            node *follow = list->next;
            // list = list->next;
            free(list); // free deleted node
            list = follow;
        }
        else
        {
            node *fetched = fetch_node(list, index);
            node *prev, *follow;
            if (index > 0)
            {
                prev = fetch_node(list, index - 1);
            }
            else
            {
                prev = list;
            }
            int range = count(list);
            if (index != range - 1 && index < range)
            {
                follow = fetch_node(list, index + 1);
            }
            else
            {
                follow = NULL;
            }
            free(prev->next); // free deleted node
            prev->next = follow;
        }
        return list;
    }
    

    【讨论】:

    • 虽然说的有道理,但似乎并没有解决问题:(
    • @OmarIbrahim 这肯定修复了帖子中报告的 main/lead/declare 泄漏,这是由于 list = delete(list, 0); 移动了列表的头部而没有释放前一个。如果还有其他问题,请edit您的问题并更新代码和新的 valgrind 输出。
    猜你喜欢
    • 2021-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 1970-01-01
    • 2014-11-17
    • 1970-01-01
    相关资源
    最近更新 更多