我在C ++中生成了一个最小的代码,导致我不明白的内存错误。
#include <queue>
using namespace std;
class A{
int *a;
public:
A() {a=new int[2];}
~A() {delete[] a;}
};
main() {
queue<A> *q=new queue<A>;
q->push(A());
//q->pop();
delete q;
}
这导致
*** Error in `./a.out': double free or corruption (fasttop): 0x000055b703ee3f30 ***
我不知道为什么。如果我取消注释q->pop()
行,它也会产生此错误,因此我有一个空队列。
Valgrind说
==17708== Invalid free() / delete / delete[] / realloc()
==17708== at 0x4C2D7DB: operator delete[](void*) (vg_replace_malloc.c:621)
==17708== by 0x108C2A: A::~A() (pokus.cpp:9)
==17708== by 0x10A003: void std::_Destroy<A>(A*) (stl_construct.h:93)
==17708== by 0x109BD0: void std::_Destroy_aux<false>::__destroy<A*>(A*, A*) (stl_construct.h:103)
==17708== by 0x109979: void std::_Destroy<A*>(A*, A*) (stl_construct.h:126)
==17708== by 0x1096EB: void std::_Destroy<A*, A>(A*, A*, std::allocator<A>&) (stl_construct.h:151)
==17708== by 0x109372: std::deque<A, std::allocator<A> >::_M_destroy_data_aux(std::_Deque_iterator<A, A&, A*>, std::_Deque_iterator<A, A&, A*>) (deque.tcc:845)
==17708== by 0x108F32: std::deque<A, std::allocator<A> >::_M_destroy_data(std::_Deque_iterator<A, A&, A*>, std::_Deque_iterator<A, A&, A*>, std::allocator<A> const&) (stl_deque.h:2035)
==17708== by 0x108CBE: std::deque<A, std::allocator<A> >::~deque() (stl_deque.h:1041)
==17708== by 0x108C45: std::queue<A, std::deque<A, std::allocator<A> > >::~queue() (stl_queue.h:96)
==17708== by 0x108B3E: main (pokus.cpp:16)
==17708== Address 0x5a86290 is 0 bytes inside a block of size 8 free'd
==17708== at 0x4C2D7DB: operator delete[](void*) (vg_replace_malloc.c:621)
==17708== by 0x108C2A: A::~A() (pokus.cpp:9)
==17708== by 0x108B2D: main (pokus.cpp:14)
==17708== Block was alloc'd at
==17708== at 0x4C2C93F: operator new[](unsigned long) (vg_replace_malloc.c:423)
==17708== by 0x108BF5: A::A() (pokus.cpp:8)
==17708== by 0x108B0E: main (pokus.cpp:14)
如果我取消注释q->pop()
,我会
==17974== Invalid free() / delete / delete[] / realloc()
==17974== at 0x4C2D7DB: operator delete[](void*) (vg_replace_malloc.c:621)
==17974== by 0x108C36: A::~A() (pokus.cpp:9)
==17974== by 0x1099A1: void __gnu_cxx::new_allocator<A>::destroy<A>(A*) (new_allocator.h:124)
==17974== by 0x10950C: void std::allocator_traits<std::allocator<A> >::destroy<A>(std::allocator<A>&, A*) (alloc_traits.h:487)
==17974== by 0x108FFD: std::deque<A, std::allocator<A> >::pop_front() (stl_deque.h:1554)
==17974== by 0x108D77: std::queue<A, std::deque<A, std::allocator<A> > >::pop() (stl_queue.h:271)
==17974== by 0x108B39: main (pokus.cpp:15)
==17974== Address 0x5a86290 is 0 bytes inside a block of size 8 free'd
==17974== at 0x4C2D7DB: operator delete[](void*) (vg_replace_malloc.c:621)
==17974== by 0x108C36: A::~A() (pokus.cpp:9)
==17974== by 0x108B2D: main (pokus.cpp:14)
==17974== Block was alloc'd at
==17974== at 0x4C2C93F: operator new[](unsigned long) (vg_replace_malloc.c:423)
==17974== by 0x108C01: A::A() (pokus.cpp:8)
==17974== by 0x108B0E: main (pokus.cpp:14)
由于某种原因,即使队列为空,它也会调用类A
的某个元素的析构函数。
答案 0 :(得分:4)
你的析构函数错误
~A() {delete a;}
应该是
~A() {delete[] a;}
您必须始终匹配new
/ delete
和new[]
/ delete[]
此外,您应该使您的类不可复制,或者定义一个用户定义的复制构造函数,为复制分配一个新数组。
事实上,我建议您将A
更改为以下
#include <array>
class A{
std::array<int, 2> a;
public:
A() = default;
};