我有一个自定义内存池,我尝试使用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字节)却被泄露了。
我应该如何重写这些析构函数,以便以正确的顺序释放所有内容?