Search code examples
c++undefined-behaviorstdthread

C++ - weird thread behavior when pass vector to method


I wrote the following code and noticed a weird behavior.

#include <iostream>
#include <vector>
#include <thread>

void withVectorArg(double waitTime, std::vector<int> q = {}) {
    std::cout << "[withVectorArg] waitTime: " << waitTime << "s" << '\n';
    std::thread thread([&waitTime]() {
        std::cout << "[withVectorArg] waitTime: " << waitTime << "s" << '\n';
    });
    thread.detach();
}

void withoutVectorArg(double waitTime) {
    std::cout << "[withoutVectorArg] waitTime: " << waitTime << "s" << '\n';
    std::thread thread([&waitTime]() {
        std::cout << "[withoutVectorArg] waitTime: " << waitTime << "s" << '\n';
    });
    thread.detach();
}

int main() {
    withVectorArg(1);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    withoutVectorArg(1);
    while (true) {}
    return 0;
}

The output of this code is:

[withVectorArg] waitTime: 1s
[withVectorArg] waitTime: 3.38411e-312s
[withoutVectorArg] waitTime: 1s
[withoutVectorArg] waitTime: 1s

Both methods do exactly the same and do not use the q variable, yet the first one somehow changes the value of waitTime.

Does someone know why this happens?

Thank you!


Solution

  • Both your functions are undefined behavior.

    The reason is that you're starting a thread, detaching it and exiting the function immediately. The thread however is capturing the parameter BY REFERENCE and thus when the code in the thread body is executed (that MAY happen AFTER you already returned from the function) the local variable that the reference is bound to does not exist any more (that local was destroyed when returning from the function).

    What happens when you enter the UB realm is simply undefined, trying to explain the exact weird behavior is a waste of time.