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

时间:2018-03-11 07:51:32

标签: c++ algorithm valgrind deque

我使用双向链表在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;
}

编辑:删除实施代码。

2 个答案:

答案 0 :(得分:3)

基本上,它不是你的代码的错,它是valgrind的。

检查具有相同问题的其他问题: Valgrind: Memory still reachable with trivial program using <iostream>

从帖子中引用:

  

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

希望有所帮助:)

答案 1 :(得分:2)

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