为什么lambda捕获的这个指针被破坏而其他变量不被破坏

Tri*_*tos 1 c++ lambda pointers c++11

我编译了(g ++ -std = c ++ 11 a.cpp)并运行以下代码:

#include <iostream>
#include <functional>

using namespace std;

class A {
    std::function<void(void)> f;
public:
    A(std::function<void(void)> pf) : f(pf) {}
    void callf() { f(); }
};

class B {
    A *a;
public:
    void test() {
        B *that = this;
        auto f = [this, that]() {
            cout << "this: " << this << " that: " << that << endl;
            delete this->a;
            cout << "this: " << this << " that: " << that << endl;
        };

        a = new A(f);
        a->callf();
    }
};

int main()
{
    B().test();
}
Run Code Online (Sandbox Code Playgroud)

它的输出是:

this: 0x7fff158c88f0 that: 0x7fff158c88f0
this: 0x1ea3000 that: 0x7fff158c88f0
Run Code Online (Sandbox Code Playgroud)

我不明白为什么捕获这个改变了它的值,而具有不同名称的相同指针没有被破坏.

编辑:

我知道lambda被破坏了,我正在生产UB,但是我不明白为什么一个变量被破坏而另一个变量没有被破坏.我不明白这种行为背后的低级细节,这是非常一致的.我想了解导致这种行为的gcc实现细节.

我进一步的调查表明,改变auto f = [this, that]auto f = [that, this]引起的被破坏.

Lig*_*ica 6

未定义的行为,无疑.你刚刚销毁了你正在执行的lambda.

  • @Trismegistos,未定义的行为可以保持一致.或者它可能不一致. (5认同)
  • 在其某个成员函数运行时销毁对象不会调用未定义的行为.在销毁对象后引用该对象. (5认同)
  • @Trismegistos此外,未定义的行为并不总是有一个简单的"低级"原因,就像某些字节的内存被覆盖一样.在某些情况下,它也可能是因为编译器可能只生成只在假设不发生UB的情况下才尝试做正确的事情的代码. (3认同)