步骤1.创建类的实例
步骤2.将此实例推送到矢量
步骤3.在实例的成员方法中调用delete this;
步骤4.一切都很好
步骤5.将某些内容推送到向量并获取此
*** glibc detected *** ./app: double free or corruption (fasttop): 0x0000000001017930 ***
======= Backtrace: =========
/lib/libc.so.6(+0x71bd6)[0x7f607d60cbd6]
/lib/libc.so.6(cfree+0x6c)[0x7f607d61194c]
./app[0x40231c]
./app[0x402290]
./app[0x4053c0]
./app[0x4048fe]
./app[0x404246]
./app[0x403fe0]
./app[0x402400]
./app[0x4035cb]
./app[0x4034d3]
/lib/libpthread.so.0(+0x68ca)[0x7f607e2b78ca]
/lib/libc.so.6(clone+0x6d)[0x7f607d66a92d]
======= Memory map: ========
00400000-0040f000 r-xp 00000000 09:03 60427370 /root/AHS/app
0060e000-0060f000 rw-p 0000e000 09:03 60427370 /root/AHS/app
01017000-01038000 rw-p 00000000 00:00 0 [heap]
7f6074000000-7f6074021000 rw-p 00000000 00:00 0
7f6074021000-7f6078000000 ---p 00000000 00:00 0
7f607a595000-7f607a596000 ---p 00000000 00:00 0
7f607a596000-7f607ad96000 rw-p 00000000 00:00 0
7f607ad96000-7f607ad97000 ---p 00000000 00:00 0
7f607ad97000-7f607b597000 rw-p 00000000 00:00 0
7f607b597000-7f607b598000 ---p 00000000 00:00 0
7f607b598000-7f607bd98000 rw-p 00000000 00:00 0
7f607bd98000-7f607bd99000 ---p 00000000 00:00 0
7f607bd99000-7f607c599000 rw-p 00000000 00:00 0
7f607c599000-7f607c59a000 ---p 00000000 00:00 0
7f607c59a000-7f607cd9a000 rw-p 00000000 00:00 0
7f607cd9a000-7f607cd9b000 ---p 00000000 00:00 0
7f607cd9b000-7f607d59b000 rw-p 00000000 00:00 0
7f607d59b000-7f607d6f4000 r-xp 00000000 09:03 60425052 /lib/libc-2.11.3.so
7f607d6f4000-7f607d8f3000 ---p 00159000 09:03 60425052 /lib/libc-2.11.3.so
7f607d8f3000-7f607d8f7000 r--p 00158000 09:03 60425052 /lib/libc-2.11.3.so
7f607d8f7000-7f607d8f8000 rw-p 0015c000 09:03 60425052 /lib/libc-2.11.3.so
7f607d8f8000-7f607d8fd000 rw-p 00000000 00:00 0
7f607d8fd000-7f607d913000 r-xp 00000000 09:03 60425245 /lib/libgcc_s.so.1
7f607d913000-7f607db12000 ---p 00016000 09:03 60425245 /lib/libgcc_s.so.1
7f607db12000-7f607db13000 rw-p 00015000 09:03 60425245 /lib/libgcc_s.so.1
7f607db13000-7f607db93000 r-xp 00000000 09:03 60425438 /lib/libm-2.11.3.so
7f607db93000-7f607dd93000 ---p 00080000 09:03 60425438 /lib/libm-2.11.3.so
7f607dd93000-7f607dd94000 r--p 00080000 09:03 60425438 /lib/libm-2.11.3.so
7f607dd94000-7f607dd95000 rw-p 00081000 09:03 60425438 /lib/libm-2.11.3.so
7f607dd95000-7f607de8b000 r-xp 00000000 09:03 60032880 /usr/lib/libstdc++.so.6.0.13
7f607de8b000-7f607e08b000 ---p 000f6000 09:03 60032880 /usr/lib/libstdc++.so.6.0.13
7f607e08b000-7f607e092000 r--p 000f6000 09:03 60032880 /usr/lib/libstdc++.so.6.0.13
7f607e092000-7f607e094000 rw-p 000fd000 09:03 60032880 /usr/lib/libstdc++.so.6.0.13
7f607e094000-7f607e0a9000 rw-p 00000000 00:00 0
7f607e0a9000-7f607e0b0000 r-xp 00000000 09:03 60425177 /lib/librt-2.11.3.so
7f607e0b0000-7f607e2af000 ---p 00007000 09:03 60425177 /lib/librt-2.11.3.so
7f607e2af000-7f607e2b0000 r--p 00006000 09:03 60425177 /lib/librt-2.11.3.so
7f607e2b0000-7f607e2b1000 rw-p 00007000 09:03 60425177 /lib/librt-2.11.3.so
7f607e2b1000-7f607e2c8000 r-xp 00000000 09:03 60425205 /lib/libpthread-2.11.3.so
7f607e2c8000-7f607e4c7000 ---p 00017000 09:03 60425205 /lib/libpthread-2.11.3.so
7f607e4c7000-7f607e4c8000 r--p 00016000 09:03 60425205 /lib/libpthread-2.11.3.so
7f607e4c8000-7f607e4c9000 rw-p 00017000 09:03 60425205 /lib/libpthread-2.11.3.so
7f607e4c9000-7f607e4cd000 rw-p 00000000 00:00 0
7f607e4cd000-7f607e4eb000 r-xp 00000000 09:03 60425293 /lib/ld-2.11.3.so
7f607e6da000-7f607e6df000 rw-p 00000000 00:00 0
7f607e6e7000-7f607e6ea000 rw-p 00000000 00:00 0
7f607e6ea000-7f607e6eb000 r--p 0001d000 09:03 60425293 /lib/ld-2.11.3.so
7f607e6eb000-7f607e6ec000 rw-p 0001e000 09:03 60425293 /lib/ld-2.11.3.so
7f607e6ec000-7f607e6ed000 rw-p 00000000 00:00 0
7fff4ee3b000-7fff4ee50000 rw-p 00000000 00:00 0 [stack]
7fff4efff000-7fff4f000000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
有人可以告诉我,这是什么,为什么会发生这种情况,我该如何解决?
答案 0 :(得分:4)
这是因为你释放了你不拥有的记忆。 vector
拥有包含其内容的内存。
delete this;
就像在你完成它之后将租车带到打捞场。不要这样做,租赁公司希望它回来!
要小心拥有记忆之间的区别,只需控制它就可以借给你。
答案 1 :(得分:2)
为属于delete this
的对象执行vector
,你犯了两大错误:
delete
,则new
是正确的匹配 - 但vector
管理的对象不是这样分配的;相反,vector
从分配器中获取一大块内存(尽可能大到它认为是合理的)并在那里复制使用放置new
推入其中的元素;所以,不仅你释放了你不拥有的记忆,你也使用了错误的方法来释放它。如果您需要从vector
删除元素,只需使用vector::erase
方法。
答案 2 :(得分:1)
如果在任何方法中执行delete this
,则必须确保在该语句之后没有其他人调用该实例的任何方法(对于任何代码)。这包括destructor
。
当你将实例推入向量时,在被销毁时,向量会调用实例的析构函数,因此double free
如果你需要一个向量,你可以将指针推送到实例,它会没问题。
然而,正如其他人所说不要使用delete this
除非绝对必要
如果您只是在函数中创建类的本地实例,那么您也会遇到问题。很可能你没有看到这种行为,因为你的程序在局部变量的范围结束之前完成。如果你试过这个:
void func() {
MyClass myClass;
myClass.theBadFunc();
}
当它返回时,您将有一个核心转储。
答案 3 :(得分:1)
这是否与您描述的代码类似?
struct MyClass {
void f() { delete this; }
};
int main() {
MyClass c;
std::vector<MyClass> v;
v.push_back(c);
c.f();
return 0;
}
矢量无关紧要。问题是delete this
调用c
的析构函数并释放构建c
的内存。该内存位于堆栈中,无法释放。不要删除堆栈对象。编译器会在超出范围时生成代码以进行清理,在本例中为main
的末尾。