如何释放C中链表中动态分配的内存

问题描述 投票:0回答:1

我尝试在 C 中实现一个链表,由于没有释放一些 malloc 的变量,我遇到了一些内存泄漏。我不确定何时以及如何释放它们,因为在使用它们之前我无法释放它们。

这是我的 insertStart 和 createLinkedList 代码

LinkedList* createLinkedList(void)
{
    LinkedList* newList;
    
    newList = (LinkedList*)malloc(sizeof(LinkedList));
    
    newList->head = NULL;
    newList->tail = NULL;
    newList->size = 0;
    
    return newList;
}

void insertStart(LinkedList* list, void* entry)
{
    void* newEntry = malloc(sizeof(Position));
    ListNode* newNd = (ListNode*)malloc(sizeof(ListNode));

    memcpy(newEntry, entry, sizeof(Position));

    newNd->data = newEntry;
    newNd->next = list->head;
    list->head = newNd;

    list->size++;
}

这两种方法主要是我泄漏的地方。

我尝试使用 valgrind,这就是它的输出,

==1385==
==1385== HEAP SUMMARY:
==1385==     in use at exit: 900 bytes in 19 blocks
==1385==   total heap usage: 78 allocs, 59 frees, 14,808 bytes allocated
==1385==
==1385== 20 bytes in 1 blocks are definitely lost in loss record 1 of 7
==1385==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1385==    by 0x109668: controls (game.c:78)
==1385==    by 0x109596: game (game.c:44)
==1385==    by 0x109455: main (main.c:49)
==1385==
==1385== 48 bytes in 2 blocks are indirectly lost in loss record 2 of 7
==1385==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1385==    by 0x10AA5B: insertStart (linkedList.c:24)
==1385==    by 0x109829: controls (game.c:114)
==1385==    by 0x109596: game (game.c:44)
==1385==    by 0x109455: main (main.c:49)
==1385==
==1385== 48 bytes in 2 blocks are indirectly lost in loss record 3 of 7
==1385==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1385==    by 0x10AA5B: insertStart (linkedList.c:24)
==1385==    by 0x1099F2: controls (game.c:144)
==1385==    by 0x109596: game (game.c:44)
==1385==    by 0x109455: main (main.c:49)
==1385==
==1385== 120 bytes in 5 blocks are indirectly lost in loss record 4 of 7
==1385==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1385==    by 0x10AA5B: insertStart (linkedList.c:24)
==1385==    by 0x109910: controls (game.c:129)
==1385==    by 0x109596: game (game.c:44)
==1385==    by 0x109455: main (main.c:49)
==1385==
==1385== 168 bytes in 7 blocks are indirectly lost in loss record 5 of 7
==1385==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1385==    by 0x10AA5B: insertStart (linkedList.c:24)
==1385==    by 0x109AD9: controls (game.c:159)
==1385==    by 0x109596: game (game.c:44)
==1385==    by 0x109455: main (main.c:49)
==1385==
==1385== 408 (24 direct, 384 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 7
==1385==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1385==    by 0x10AA5B: insertStart (linkedList.c:24)
==1385==    by 0x109AD9: controls (game.c:159)
==1385==    by 0x109596: game (game.c:44)
==1385==    by 0x109455: main (main.c:49)
==1385==
==1385== 472 bytes in 1 blocks are still reachable in loss record 7 of 7
==1385==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1385==    by 0x48DF64D: __fopen_internal (iofopen.c:65)
==1385==    by 0x48DF64D: fopen@@GLIBC_2.2.5 (iofopen.c:86)
==1385==    by 0x109347: main (main.c:26)
==1385==
==1385== LEAK SUMMARY:
==1385==    definitely lost: 44 bytes in 2 blocks
==1385==    indirectly lost: 384 bytes in 16 blocks
==1385==      possibly lost: 0 bytes in 0 blocks
==1385==    still reachable: 472 bytes in 1 blocks
==1385==         suppressed: 0 bytes in 0 blocks
==1385==
==1385== For lists of detected and suppressed errors, rerun with: -s
==1385== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

我也搜了一下,尝试实现这个deleteAll方法,但是好像还是不行。

void deleteAll(LinkedList* list)
{
    while (list->head != NULL)
    {
        ListNode* temp = list->head->data;
        list->head = list->head->next;
        free(temp);
    }
}

我已经更新了我的deleteAll函数,现在这是Valgrind的输出。

==3055==
==3055== HEAP SUMMARY:
==3055==     in use at exit: 20 bytes in 1 blocks
==3055==   total heap usage: 72 allocs, 71 frees, 14,676 bytes allocated
==3055==
==3055== 20 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3055==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3055==    by 0x10AA80: insertStart (linkedList.c:22)
==3055==    by 0x109A1E: controls (game.c:144)
==3055==    by 0x1095C2: game (game.c:44)
==3055==    by 0x109475: main (main.c:49)
==3055==
==3055== LEAK SUMMARY:
==3055==    definitely lost: 20 bytes in 1 blocks
==3055==    indirectly lost: 0 bytes in 0 blocks
==3055==      possibly lost: 0 bytes in 0 blocks
==3055==    still reachable: 0 bytes in 0 blocks
==3055==         suppressed: 0 bytes in 0 blocks
==3055==
==3055== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

现在说泄漏来自

void* newEntry = malloc(sizeof(Position));

c memory-leaks linked-list malloc
1个回答
1
投票

deleteAll
仅释放
insertStart
分配的块之一。另外,我不知道你是否希望它也释放
createLinkedList
分配的块。
temp
中的
deleteAll
变量实际上指向
Position
,而不是
ListNode

试试这个:

void deleteAll(LinkedList* list)
{
    while (list->head != NULL)
    {
        ListNode* temp = list->head;
        list->head = list->head->next;
        free(temp->data);
        free(temp);
    }
    free(list); // not sure if you want this or not
}
© www.soinside.com 2019 - 2024. All rights reserved.