c ++ - 从破坏的函数对象返回后,`this`指针变为null

时间:2014-12-19 07:41:18

标签: c++ c++11 memory-management g++ clang++

以下代码

#include <functional>
#include <iostream>

class State {
    void first_shot()
    {
        std::cout << "foo start " << this << std::endl;
        this->x = [=]()
        {
            std::cout << "baz " << this << std::endl;
        };
        std::cout << "foo end " << this << std::endl;
    }
public:
    std::function<void()> x;

    State()
    {
        this->x = [=]()
        {
            std::cout << "bar start " << this << std::endl;
            this->first_shot();

            /* HERE */
            std::cout << "bar end " << this << std::endl;
        };
    }
};

int main()
{
    State s;
    s.x();
    s.x();
    return 0;
}
使用g++ -std=c++0x进行编译时,

非常奇怪。在评论HERE之后的行中,this变为空指针。实际上,只要this->xthis->first_shot()期间更改为空函数指针或绑定到任何其他函数,this将在调用后更改为null。

我在Ubuntu 14.04 x64和CentOS 7(都是g ++ 4.8.2)下进行了测试。使用clang ++进行编译时,它不可重现(this指针不会改变)。

这是对std::function的误用吗?当函数对象被销毁时,绑定到它的值(在这种情况下为this)变得无效,这是相当可观的。

所以我想通过对后一个lambda

的简单修改来解决这个问题
this->x = [=]()
{
    State* me = this;
    std::cout << "bar start " << me << std::endl;
    me->first_shot();
    std::cout << "bar end " << me << std::endl;
};

固定代码没问题,不是吗?

顺便说一下,在我编译之前使用g ++运行它,二进制clang ++生成运行没有任何问题,即使使用valgrind也不会出现内存错误。我想知道clang是怎么做的“恰到好处”(它恰到好处吗?)

0 个答案:

没有答案