简体   繁体   English

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

[英]Why does this Deque destructor have memory leak

I use doubly linked list to implement Deque in C++. 我使用双向链表在C ++中实现Deque。

Destructor: 析构函数:

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

    this->right_p = NULL;
}

when i use valgrind --leak-check=full ./a.out to check memory leak just to test my destructor` I got the following output: 当我使用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)

I can't figure out why there is still ONE out of 1003 allocs not being free. 我不明白为什么1003分配中仍然有一个不是免费的。

Why do i have one memory leak? 为什么我有一次内存泄漏? what is wrong with my destructor? 我的析构函数怎么了?

Test code here: 在这里测试代码:

/* 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;
}

edit: remove implementation code. 编辑:删除实现代码。

Essentially, it's not your code's fault, it's valgrind's. 本质上,这不是代码的错误,而是valgrind的错误。

Check this other question that has had the same problem: Valgrind: Memory still reachable with trivial program using <iostream> 请检查存在相同问题的另一个问题: Valgrind:使用<iostream>的普通程序仍然可以访问内存

Quoting from the 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. C ++标准库的许多实现都使用它们自己的内存池分配器。 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. 大量销毁对象的内存不会立即释放并交还给OS,而是保留在池中供以后重用。 The fact that the pools are not freed at the exit of the program cause Valgrind to report this memory as still reachable. 程序退出时未释放池的事实导致Valgrind报告此内存仍可访问。 The behaviour not to free pools at the exit could be called a bug of the library though. 但是,在出口处不释放池的行为可以称为库的错误。

Hope that helps :) 希望有帮助:)

The memory leak reported by valgrind does not appear to be in your code: 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)

This appears to be a heap allocation from within a constructor of a global object. 这似乎是全局对象的构造函数中的堆分配。 (In theory, it could still come from your code if operator new is called as a tail call, so that it does not show up in the backtrace, but I don't see such an object declaration in your cdoe.) (理论上,如果将operator new称为尾调用,它仍然可能来自您的代码,这样它就不会显示在回溯中,但我在cdoe中看不到这样的对象声明。)

It is also not an actual leak, it is just some data allocated on the heap at program start. 这也不是实际的泄漏,它只是程序启动时在堆上分配的一些数据。 If you install debugging information for libstdc++ , then you might get a hint of what is actually being allocated. 如果为libstdc++安装调试信息,则可能会提示您实际分配了什么。 Then you could also set a breakpoint on call_init and step through the early process initialization, to see the constructors that are called. 然后,您还可以在call_init上设置一个断点,并逐步进行早期的进程初始化,以查看被调用的构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM