Vivek
Vivek

Reputation: 450

Function call inside lamda of thread C++

class Box {
    int _value;
public:
    Box(int value_):_value(value_) {}
    int getValue() const {return _value;}
};

void setBox(unsigned value, Box& box_) {
    box_ = value == 1 ? Box(1): Box(2);
}

int main()
{
    Box box1(0), box2(0);
    std::vector<std::thread> threadList;
    for(unsigned value : {1, 2}) {
        threadList.push_back(
            std::thread([&](){
                    setBox(
                        value,
                        (value == 1 ? std::ref(box1) : std::ref(box2)));
                }));

    }
    for(auto& thread:threadList) {
        thread.join();
    }
    std::cout << "Box1:" << box1.getValue() << std::endl;
    std::cout << "Box2:" << box2.getValue() << std::endl;
}

Output

Box1:0
Box2:2

Why is the Box1 value 0 not 1. I know something is wrong with the code. Not sure what exactly is the issue. How exactly does lambda work here?

Upvotes: 2

Views: 59

Answers (1)

songyuanyao
songyuanyao

Reputation: 173014

Your code has potential undefined behavior. The capture list [&] captures value as reference too. value is a local variable in the for loop, and will be destroyed when the iteration ends, after that the captured reference becomes dangled.

You can change it to capturing value by value.

for(unsigned value : {1, 2}) {
    threadList.push_back(
        std::thread([&,value](){
        //            ^^^^^^
                setBox(
                    value,
                    (value == 1 ? std::ref(box1) : std::ref(box2)));
            }));
}

Upvotes: 4

Related Questions