【发布时间】:2018-06-26 18:04:50
【问题描述】:
对于我正在编写的程序,我编写了一个简单的数组包装类(想法是它应该是固定大小的。我知道我可以只使用 std::vectors)
删除数组时遇到问题。
这些是我的构造函数:
template <class T>
Array<T>::Array(size_t size): m_data(new T[size]), m_size(size)
{}
template <class T>
Array<T>::Array(const std::vector<T> &vec): m_size(vec.size())
{
std::allocator<T> a;
m_data = a.allocate(m_size);
for(int i = 0; i<m_size; i++)
{
new (m_data+i) T(vec[i]);
}
}
这是我的析构函数:
template <class T>
Array<T>::~Array()
{
delete[] m_data;
}
我使用 valgrind 试图弄清楚发生了什么,但它没有帮助。
==20840== Invalid read of size 8
==20840== at 0x10ABB8: sapph_dijkstra::Array<sapph_dijkstra::Node>::~Array() (in /home/sapphie/dijkstra/test)
==20840== by 0x1091CF: sapph_dijkstra::MinHeap::~MinHeap() (minheap.h:40)
==20840== by 0x109021: main (test.c:20)
==20840== Address 0x5b21318 is 8 bytes before a block of size 400 alloc'd
==20840== at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20840== by 0x109F99: __gnu_cxx::new_allocator<sapph_dijkstra::Node>::allocate(unsigned long, void const*) (new_allocator.h:111)
==20840== by 0x10AA36: sapph_dijkstra::Array<sapph_dijkstra::Node>::Array(std::vector<sapph_dijkstra::Node, std::allocator<sapph_dijkstra::Node> > const&) (in /home/sapphie/dijkstra/test)
==20840== by 0x10A232: sapph_dijkstra::MinHeap::MinHeap(std::vector<sapph_dijkstra::Node, std::allocator<sapph_dijkstra::Node> > const&) (in /home/sapphie/dijkstra/test)
==20840== by 0x108FD1: main (test.c:20)
==22059== Invalid free() / delete / delete[] / realloc()
==22059== at 0x4C3173B: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22059== by 0x10ABA4: sapph_dijkstra::Array<sapph_dijkstra::Node>::~Array() (in /home/sapphie/dijkstra/test)
==22059== by 0x1091CF: sapph_dijkstra::MinHeap::~MinHeap() (minheap.h:40)
==22059== by 0x109021: main (test.c:20)
(我已经删除了一些相同的错误消息)
在我完成的打印中,我发现我分配的地址是0x5b21320,所以valgrind 显示的地址确实是在那之前的8 个字节。
但我不明白为什么。我似乎无法访问它。
我错过了什么琐碎的事情吗?
我意识到对于一个我可以只使用标准向量的问题,这可能是一个过于复杂的解决方案,我可能会改变它。但我现在主要是好奇。
【问题讨论】:
-
a.allocate(m_size);是做什么的? -
这是在初始化任何东西之前为数组分配内存。这样,如果 T 没有默认构造函数,而只有一个复制构造函数,则此代码仍然有效(在我的情况下,我有一个默认构造函数没有意义的类)
标签: c++ memory valgrind new-operator delete-operator