indexação de array c ++ com valor não const [duplicado]

Nov 09 2020

Eu tenho o seguinte código:

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
    });
}

Eu defini um construtor de cópia para displayObject, mas o código acima me dá uma falha de segmentação na linha destacada. Posso resolver esse problema da seguinte maneira:

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);
    });
}

Eu me pergunto por que uma indexação de variável me dará falha de segmentação

Respostas

3 SamVarshavchik Nov 09 2020 at 22:03

Em seu thread de execução

conveyor_belts[j * 2].draw(15, 78 + i * 3);

C ++ não oferece nenhuma garantia de que o novo encadeamento de execução executará este código e lerá o valor jque foi capturado por referência antes que o encadeamento de execução original itere o forloop e aumente o valor de jser referenciado aqui. Tudo o que o C ++ garante é que o novo thread de execução comece a ser executado em algum ponto após std::thread ser construído. Essa é a sua única garantia.

É bastante provável que no momento em que todos os encadeamentos de execução acordem, o forloop já terminou de iterar e todos os quatro encadeamentos de execução estão olhando para sua referência capturada para j, que agora atingiu seu valor final de 4, e todos os quatro encadeamentos de execução ficarão felizes use o valor de j, que é agora 4, porque foi capturado por referência.