我写了一个简单的类:
class A
{
private:
// a bunch of attributes
int *a;
public:
A() {
cout << "constructor called" << endl;
}
~A() {
cout << "destructor called" << endl;
if (a) delete[] a;
}
void initialize(int i) {
//does the initialization
a = new int[i];
}
};
,在我的程序中,我试图构建这些对象的向量,但我得到double free or corruption
错误:
int main()
{
vector<A> a;
for (int i=0; i<10; i++) {
a.resize(a.size()+1);
a[a.size()-1].initialize(i);
}
}
事实上,当我运行这个程序时,我期望在此之后得到10条消息constructor called
和10条消息destructor called
,但我得到了这个输出:
constructor called
destructor called
constructor called
destructor called
destructor called
constructor called
destructor called
*** glibc detected *** ./test.o: double free or corruption (fasttop): 0x00000000022bc030 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7f823cd49b96]
./test.o[0x400d3b]
./test.o[0x401924]
./test.o[0x401672]
./test.o[0x401107]
./test.o[0x400fb5]
./test.o[0x4014d5]
./test.o[0x401012]
./test.o[0x400e79]
./test.o[0x400bd1]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f823ccec76d]
./test.o[0x400ac9]
======= Memory map: ========
00400000-00403000 r-xp 00000000 00:20 286720734 /home/users/u5410055/Desktop/test.o
00602000-00603000 r--p 00002000 00:20 286720734 /home/users/u5410055/Desktop/test.o
00603000-00604000 rw-p 00003000 00:20 286720734 /home/users/u5410055/Desktop/test.o
022bc000-022dd000 rw-p 00000000 00:00 0 [heap]
7f823c9cf000-7f823caca000 r-xp 00000000 08:03 721005 /lib/x86_64-linux-gnu/libm-2.15.so
7f823caca000-7f823ccc9000 ---p 000fb000 08:03 721005 /lib/x86_64-linux-gnu/libm-2.15.so
7f823ccc9000-7f823ccca000 r--p 000fa000 08:03 721005 /lib/x86_64-linux-gnu/libm-2.15.so
7f823ccca000-7f823cccb000 rw-p 000fb000 08:03 721005 /lib/x86_64-linux-gnu/libm-2.15.so
7f823cccb000-7f823ce80000 r-xp 00000000 08:03 720994 /lib/x86_64-linux-gnu/libc-2.15.so
7f823ce80000-7f823d080000 ---p 001b5000 08:03 720994 /lib/x86_64-linux-gnu/libc-2.15.so
7f823d080000-7f823d084000 r--p 001b5000 08:03 720994 /lib/x86_64-linux-gnu/libc-2.15.so
7f823d084000-7f823d086000 rw-p 001b9000 08:03 720994 /lib/x86_64-linux-gnu/libc-2.15.so
7f823d086000-7f823d08b000 rw-p 00000000 00:00 0
7f823d08b000-7f823d0a0000 r-xp 00000000 08:03 30391 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f823d0a0000-7f823d29f000 ---p 00015000 08:03 30391 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f823d29f000-7f823d2a0000 r--p 00014000 08:03 30391 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f823d2a0000-7f823d2a1000 rw-p 00015000 08:03 30391 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f823d2a1000-7f823d383000 r-xp 00000000 08:03 390571 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7f823d383000-7f823d582000 ---p 000e2000 08:03 390571 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7f823d582000-7f823d58a000 r--p 000e1000 08:03 390571 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7f823d58a000-7f823d58c000 rw-p 000e9000 08:03 390571 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7f823d58c000-7f823d5a1000 rw-p 00000000 00:00 0
7f823d5a1000-7f823d5c3000 r-xp 00000000 08:03 721006 /lib/x86_64-linux-gnu/ld-2.15.so
7f823d796000-7f823d79b000 rw-p 00000000 00:00 0
7f823d7bf000-7f823d7c3000 rw-p 00000000 00:00 0
7f823d7c3000-7f823d7c4000 r--p 00022000 08:03 721006 /lib/x86_64-linux-gnu/ld-2.15.so
7f823d7c4000-7f823d7c6000 rw-p 00023000 08:03 721006 /lib/x86_64-linux-gnu/ld-2.15.so
7fff1f4c4000-7fff1f4e5000 rw-p 00000000 00:00 0 [stack]
7fff1f564000-7fff1f565000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted (core dumped)
语法错误吗?我应该在代码中考虑哪些更改?
你的问题绝对与vector
无关。我可以不使用vector
复制你的问题。
在继续之前,试着让你的类可以运行下面的程序:
int main()
{
A a1;
a1.initialize(1);
A a2 = a1;
A a3;
a3 = a1;
}
这个程序必须完成没有错误,没有内存泄漏,没有崩溃,没有双重删除等。一旦您让这个小程序与您的类一起工作,然后并且只有当您才能考虑将其放置在容器中,例如vector
。
上面的程序执行构造、复制/赋值和销毁操作,所有vector
将/可能对其内部对象执行的操作。
上面程序的一个变化是删除对a1.initialize
的调用,看看会发生什么(这将测试如果A只是默认构造会发生什么)。
这并不是说你创建这个向量的方式看起来是个好主意,但我注意到的直接问题是,你没有初始化类a的a
成员。
这个/将/爆炸一旦医生被调用,除非在此之前调用initialize()。
向量中的10个对象的指针*a都指向同一个地址,所以你得到了双自由