std::函数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);,它会很好地工作(,但我仍然不明白该代码有什么问题,以及为什么它不起作用。

但我仍然不明白该代码有什么问题,以及为什么它不起作用。

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

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

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

最新更新