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

Why does this Deque destructor have memory leak

本文关键字:内存 泄漏 析构函数 Deque 为什么      更新时间:2023-10-16

我使用双链表在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 << "nnDeque Class Test Program 6 - STARTnn";
    // 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 << "nnDeque Class Test Program 6 - DONEnn";
    return 0;
}

编辑:删除实现代码。

从本质上讲,这不是你的代码的错,而是valgrind的错。

检查另一个有相同问题的问题:瓦尔格林德:使用

引用

帖子:

首先:放松,它可能不是一个错误,而是一个功能。C++ 标准库的许多实现都使用自己的内存池分配器。相当多的已销毁对象的内存不会立即释放并返回给操作系统,而是保留在池中以供以后重用。在程序退出时池未释放的事实导致 Valgrind 将此内存报告为仍然可以访问。不过,不在出口处释放池的行为可以称为库的错误。

希望对:)有所帮助

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上设置断点,并逐步完成早期进程初始化,以查看调用的构造函数。