【发布时间】:2021-02-21 20:29:53
【问题描述】:
我有以下代码:
DisplayObject conveyor_belts[] = {eggs_1, eggs_2, flour_1, flour_2, sugar_1, sugar_2, butter_1, butter_2};
std::thread conveyor_belts_t[4];
for (int j = 0; j < 4; j++) {
conveyor_belts_t[j] = std::thread([&](){
conveyor_belts[j * 2].draw(15, 78 + i * 3); // segmentation fault here
});
}
我为 displayObject 定义了一个复制构造函数,但上面的代码在突出显示的行处给出了分段错误。我可以通过以下方式解决此问题:
DisplayObject conveyor_belts[] = {eggs_1, eggs_2, flour_1, flour_2, sugar_1, sugar_2, butter_1, butter_2};
std::thread conveyor_belts_t[4];
for (int j = 0; j < 4; j++) {
conveyor_belts_t[j] = std::thread([&](){
conveyor_belts[0].draw(15, 78 + i * 3);
});
}
我想知道为什么变量索引会给我分段错误
【问题讨论】:
-
您通过reference自动捕获了循环变量
j。这是不正确的。您必须在 lambda 的捕获列表中按值捕获j。作为个人风格偏好,我从不使用自动捕捉。我更愿意明确说明我给 lambda 的确切内容。 -
@paddy 谢谢,这行得通!你能详细说明为什么我不能通过引用捕获 j 吗?
-
因为它会改变然后被销毁,而你的线程都将尝试使用它。此外,这是不正确的。您希望每个线程都使用
j在创建线程时所具有的特定值。按价值捕获是做到这一点的方法。 -
如果
j在您读取它时超出范围,您将有未定义的行为。如果你碰巧在它到达4时读到它,你会得到4 * 2并越界访问数组。同样,未定义的行为。