std::function 段错误的自修改向量
Self modifying vector of 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 函数时出现段错误。
$ v0
$ Erreur de segmentation (core dumped)
我知道问题与向量重新分配有关(因为如果我在调用 V0 之前添加 v.reserve(10);
它工作正常),但我仍然不明白该代码有什么问题以及为什么它没有't/shouldn没用。
but I still don't understand what is wrong with that code and why it doesn't/shouldn't work.
当vector重新分配时,存储在其中的对象在被复制后被销毁。
因此,正在执行的 lambda 已被销毁,当您尝试访问被销毁的 lambda 的捕获引用 v
时,程序的行为是未定义的。
如果 std::function
的移动构造函数是 noexcept(它将在 C++20 中),vector 将改为移动元素,在这种情况下,lambda 将保持不变。
我正在尝试定义一个函数向量。调用函数时,它们可以在向量中添加或删除项目。
超级简化它就像下面的代码。
#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 函数时出现段错误。
$ v0
$ Erreur de segmentation (core dumped)
我知道问题与向量重新分配有关(因为如果我在调用 V0 之前添加 v.reserve(10);
它工作正常),但我仍然不明白该代码有什么问题以及为什么它没有't/shouldn没用。
but I still don't understand what is wrong with that code and why it doesn't/shouldn't work.
当vector重新分配时,存储在其中的对象在被复制后被销毁。
因此,正在执行的 lambda 已被销毁,当您尝试访问被销毁的 lambda 的捕获引用 v
时,程序的行为是未定义的。
如果 std::function
的移动构造函数是 noexcept(它将在 C++20 中),vector 将改为移动元素,在这种情况下,lambda 将保持不变。