C++11 据我所知,这个lambda调用应该是无效的,但它不会崩溃。为什么?

C++11 据我所知,这个lambda调用应该是无效的,但它不会崩溃。为什么?,c++11,lambda,C++11,Lambda,我很难理解为什么下面的代码没有崩溃 class MyClass { public: MyClass() { m_contents = 0xF0F0F0F0; } void Hello() { printf("Hello, address: %llx, contents: %x, size: %d\n", (long long int)this, m_contents, sizeof(MyClass)); } int m_contents; }; int main(

我很难理解为什么下面的代码没有崩溃

class MyClass
{
public:
    MyClass() {    m_contents = 0xF0F0F0F0; }
    void Hello() { printf("Hello, address: %llx, contents: %x, size: %d\n", (long long int)this, m_contents, sizeof(MyClass)); }
    int m_contents;
};

int main()
{
    MyClass* MyObj = new MyClass();
    MyObj->Hello();

    auto MyLambda = [MyObj]()
    {
        if (MyObj != nullptr)
        {
            MyObj->Hello();
        }
    };

    memset(MyObj, 0, sizeof(MyClass));
    MyObj->Hello();
    delete MyObj;
    MyObj = nullptr;

    MyLambda();

    return 0;
}
这是输出:

Hello, address: 1ddb4a16100, contents: f0f0f0f0, size: 4
Hello, address: 1ddb4a16100, contents: 0, size: 4
Hello, address: 1ddb4a16100, contents: dddddddd, size: 4
我本以为lambda调用会崩溃,因为我清除了它用来调用Hello()函数的所有内存。我知道内容已被擦除,因为m_内容变为0。在调用delete之后,m_contents会变成一个随机值,但是仍然会调用Hello(),并且不会发生崩溃

跟进问题: 在我将其作为捕获传递的lambda中,在调用lambda时是否有可能变为null或无效?

[MyObj](){}
不通过引用而通过值捕获指针
MyObj
。这意味着将在创建lambda时复制
MyObj
的值。因此,即使将
MyObj
设置为nullptr,lambda仍将使用其原始值,该值仍指向内存中的同一区域

在调用lambda时,位于
*MyObj
的对象已经被删除,所有
0xdd
字节都可以看到该对象(至少在调试模式下)

如果要编写
[&MyObj](){}
,则
MyObj
将被捕获为引用,这意味着lambda将始终使用捕获指针的当前值。在这种情况下,行为首先应该与您预期的完全一致:lambda中的nullptr检查将失败,并且不会调用
Hello()


至于你的后续问题:传递
这个
与任何其他符号的作用没有什么不同。通过值传递它将创建一个副本,该副本将始终允许您访问该对象,即使在该对象的生存期之后也是如此(由此产生的所有风险)。只要this指针有效,通过引用传递它就会起作用,只要方法的作用域有效,它就可能起作用。

非常感谢您的回答。我将
[MyObj]()
更改为
[&MyObj]()
,程序的行为与您描述的完全相同。