-1

步骤 1. 创建一个类的实例

步骤 2. 将此实例推送到向量

Step 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

有人可以告诉我,这是什么,为什么会发生这种情况以及如何解决?

4

4 回答 4

4

这是因为你释放了你不拥有的内存。vector拥有包含其内容的内存。

delete this;就像用完一辆租来的汽车去打捞场一样。不要那样做,租赁公司希望它回来!

注意拥有记忆和仅仅控制它借给你之间的区别。

于 2012-08-23T21:19:28.340 回答
2

delete this为属于你的对象做vector两个大错误:

  1. 它是管理存储该实例的内存的向量(它分配它,释放它,......),所以你不应该弄乱它。换句话说,既然你不拥有那段记忆,你就必须不理它。
  2. delete如果对象被分配了,则为正确匹配new- 但由 管理的对象vector不是这样分配的;取而代之的是,vector从分配器中获取一块内存(与它认为合理的一样大)并在那里复制使用放置推入其中的元素new;因此,您不仅释放了不属于您的内存,而且还使用了错误的方法来释放它。

如果您需要从 a 中删除元素vector,只需使用该vector::erase方法。

于 2012-08-23T21:24:08.310 回答
1

如果您delete this使用任何方法,您必须确保在该语句之后没有其他人调用实例的任何方法(就此而言,任何代码)。这包括destructor.

当您将实例推入向量时,在被销毁时,向量会调用实例的析构函数,因此double free

如果您需要一个向量,您可以将指针推送到该实例,这样就可以了。

但是,正如其他人所说,除非绝对必要,否则不要使用delete this

如果您只是在函数中创建类的本地实例,您也会遇到问题。很可能您没有看到此行为,因为您的程序在局部变量的范围结束之前完成。如果你试过这个:

void func() {
    MyClass myClass;
    myClass.theBadFunc();
}

当它返回时,您将有一个核心转储。

于 2012-08-23T21:26:13.740 回答
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.

于 2012-08-23T21:37:57.840 回答