提问者:小点点

STD::Function segfault的自修改向量


我试着定义一个函数向量。 当函数被调用时,它们可以从向量中添加或删除项。

超简化的,就像下面的代码。

#include <functional>
#include <vector>

int main()
{
    using F = std::function<void()>;
    std::vector<F> v;
    v.push_back([&v]{
        puts("v0");
        v.push_back([]{puts("v1");});
        v.push_back([]{puts("v2");});
        v.push_back([]{puts("v3");});
        v.push_back([]{puts("v4");});
        v.push_back([]{puts("v4");});
        v.push_back([]{puts("v5");});
        v.push_back([]{puts("v6");});
    });
    v[0]();
}

代码编译得很好,但是当运行它时,调用V0函数时会出现segfault。

$ v0
$ Erreur de segmentation (core dumped)

我知道这个问题与向量重新分配有关(因为如果我在调用V0之前添加一个v.reserve(10);,它可以正常工作),但我仍然不明白该代码有什么问题,以及为什么它不/不应该工作。


共1个答案

匿名用户

但我还是不明白那个代码有什么问题,为什么它不/不应该工作。

当向量重新分配时,存储在其中的对象在被复制后被销毁。

因此,正在执行的lambda已经被销毁,并且当您试图访问被销毁的lambda的捕获引用v时,程序的行为是未定义的。

如果std::function的move构造函数是noexcept(在C++20),vector将移动元素,在这种情况下lambda将保持原样。