在池分配器中查找内存泄漏的原因

时间:2016-12-11 05:07:49

标签: c++ memory-management memory-leaks

我有一个自定义内存池,我尝试使用STL容器,并且我使用std :: allocator模板作为我的实现的包装器。我无法追查Valgrind报告的内存泄漏原因。

我的分配器模板设置如下:

    template <class T> class pool_allocator
    {
    public:
        typedef T                 value_type;
        typedef value_type*       pointer;
        typedef const value_type* const_pointer;
        typedef value_type&       reference;
        typedef const value_type& const_reference;
        typedef std::size_t       size_type;
        typedef std::ptrdiff_t    difference_type;

        template <class U>
        pool_allocator(const pool_allocator<U>&) {}

        template <class U>
        struct rebind
        {
            typedef pool_allocator<U> other;
        };

        pool_allocator(size_type blocks,
                          size_type size_of_each_block=sizeof(T)) :
                          _pool(new MyPool<T>())
        {
            _pool->create_pool(blocks, size_of_each_block);
        }

        ... etc.

   private:
        MyPool<T>* _my_pool;

        ... etc.

它在大多数情况下工作正常,但是当我尝试将分配器与std :: vector一起使用时,当向量超出范围时我会出现内存泄漏。

当MyPool的析构函数如下所示时,&#34; _m_mem_start&#34;是从&#34; new&#34;的调用返回的指针。对于适当大小的块字节数组,以保存类型为T的n个对象:

~MyPool()
{
  delete [] reinterpret_cast<uint8_t*>(_m_mem_start);
  _m_mem_start = reinterpret_cast<uintptr_t>(nullptr);
}

pool_allocator的析构函数如下:

~pool_allocator()
{
    delete _my_pool;
}

Valgrind报告如下问题:

InvalidRead|====|Invalid read of size 8|
||Call stack:|
/home/matt/Documents/C++/Pool/include/MyPool.h|19|0x400E34: MyPool<A>::~MyPool()|
/home/matt/Documents/C++/Pool/include/pool_allocator.h|40|0x400CB4: pool_allocator<A>::~pool_allocator()|
/home/matt/Documents/C++/Pool/main.cpp|19|0x400B55: main|
||Address 0x5ab5ca0 is 32 bytes inside a block of size 48 free'd|
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so||0x4C2F24B: operator delete(void*)|
/home/matt/Documents/C++/Pool/include/pool_allocator.h|40|0x400CBC: pool_allocator<A>::~pool_allocator()|
/usr/include/c++/5/bits/stl_vector.h|79|0x400E73: std::_Vector_base<A, pool_allocator<A> >::_Vector_impl::~_Vector_impl()|
/usr/include/c++/5/bits/stl_vector.h|161|0x400F35: std::_Vector_base<A, pool_allocator<A> >::~_Vector_base()|
/usr/include/c++/5/bits/stl_vector.h|425|0x400D69: std::vector<A, pool_allocator<A> >::~vector()|
/home/matt/Documents/C++/Pool/main.cpp|20|0x400B49: main|
InvalidWrite|====|Invalid write of size 8|

etc.

在我看来,我试图从已经免费编辑的MyPool类对象中读取成员变量数据。 Valgrind还报告说,缓冲区中的字节,比如12个字节乘以10,对于每个大小为12的10个POD对象的池大小,都已丢失。

但是如果我改变pool_allocator的析构函数来调用MyPool的析构函数,就像这样:

~pool_allocator()
{
    _my_pool->~MyPool();
}

Valgrind报道:

Leak_DefinitelyLost|====|48 bytes in 1 blocks are definitely lost in loss record 1 of 2|
||Call stack:|
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so||0x4C2E0EF: operator new(unsigned long)|
/home/matt/Documents/C++/Pool/include/pool_allocator.h|28|0x400C0E: pool_allocator<A>::pool_allocator(unsigned long, unsigned long)|
/home/matt/Documents/C++/Pool/main.cpp|19|0x400AD3: main|
||Valgrind found 1 errors!|

看起来MyPool内部缓冲区已经适当地自由编辑,但是MyPool内部的成员数据(总是大小为48字节)却被泄露了。

我应该如何重写这些析构函数,以便以正确的顺序释放所有内容?

0 个答案:

没有答案