为什么这个Deque析构函数有内存泄漏

Why does this Deque destructor have memory leak

我使用双向链表在 C++ 中实现 Deque。

析构函数:

Deque::~Deque() 
{
    while (this->left_p) 
    {
        node *temp = this->left_p;
        this->left_p = this->left_p->next;
        delete temp;
    }

    this->right_p = NULL;
}

当我使用 valgrind --leak-check=full ./a.out 检查内存泄漏只是为了测试我的析构函数时,我得到了以下输出:

==2636== 
==2636== HEAP SUMMARY:
==2636==     in use at exit: 72,704 bytes in 1 blocks
==2636==   total heap usage: 1,003 allocs, 1,002 frees, 97,760 bytes allocated
==2636== 
==2636== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==2636==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2636==    by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==2636==    by 0x40106B9: call_init.part.0 (dl-init.c:72)
==2636==    by 0x40107CA: call_init (dl-init.c:30)
==2636==    by 0x40107CA: _dl_init (dl-init.c:120)
==2636==    by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==2636== 
==2636== LEAK SUMMARY:
==2636==    definitely lost: 0 bytes in 0 blocks
==2636==    indirectly lost: 0 bytes in 0 blocks
==2636==      possibly lost: 0 bytes in 0 blocks
==2636==    still reachable: 72,704 bytes in 1 blocks
==2636==         suppressed: 0 bytes in 0 blocks
==2636== 
==2636== For counts of detected and suppressed errors, rerun with: -v
==2636== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

我不明白为什么 1003 个分配中仍有一个不是空闲的。

为什么我有一处内存泄漏?我的析构函数有什么问题?

测试代码在这里:

/* Deque Test Program 6 */
#include <cstring>
#include <iostream>
#include "Deque.h"

using namespace std ;

int main (int argc, char * const argv[]) {
    cout << "\n\nDeque Class Test Program 6 - START\n\n";

    // Make a Deque
    Deque * dq1 = new Deque();
    for( int i = 0 ; i<1 ; i++ ){
        dq1->push_left(1);
        // dq1->display();
    }
    cout << "Size=" << dq1->size() << endl ;

    // The destructor should delete all the nodes.
    delete dq1 ;

    cout << "\n\nDeque Class Test Program 6 - DONE\n\n";
    return 0;
}

编辑:删除实现代码。

本质上,这不是您的代码的错,而是 valgrind 的错。

检查另一个有同样问题的问题:

引用自post:

First of all: relax, it's probably not a bug, but a feature. Many implementations of the C++ standard libraries use their own memory pool allocators. Memory for quite a number of destructed objects is not immediately freed and given back to the OS, but kept in the pool(s) for later re-use. The fact that the pools are not freed at the exit of the program cause Valgrind to report this memory as still reachable. The behaviour not to free pools at the exit could be called a bug of the library though.

希望对您有所帮助:)

valgrind 报告的内存泄漏似乎不在您的代码中:

==2636== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==2636==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2636==    by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==2636==    by 0x40106B9: call_init.part.0 (dl-init.c:72)
==2636==    by 0x40107CA: call_init (dl-init.c:30)
==2636==    by 0x40107CA: _dl_init (dl-init.c:120)

这似乎是全局对象构造函数中的堆分配。 (理论上,如果 operator new 被称为尾调用,它仍然可能来自您的代码,因此它不会出现在回溯中,但我在您的 cdoe 中没有看到这样的对象声明。)

这也不是真正的泄漏,它只是程序启动时在堆上分配的一些数据。如果您为 libstdc++ 安装调试信息,那么您可能会得到实际分配的提示。然后您还可以在 call_init 上设置断点并逐步完成早期进程初始化,以查看调用的构造函数。