0

As i said in the title im having an issue while trying to print coordinate values like this while using a std::thread

#include <array>
#include <thread>


struct Vec2
{
    int x;
    int y;
};

void dostuff2(Vec2 x)
{
    std::cout << x.x << x.y << " ";
}

void dostuff(Vec2 Oven[3])
{
    for (int i=0; i<3; ++i)
    {
        dostuff2(Oven[i]);
    }
}

int main()
{
    Vec2 Oven[3]{ {63,21},{63,22},{63,23} };
    std::thread thread_obj(dostuff,std::ref(Oven));
    thread_obj.detach();
} 

Any ideas why this code isnt working? It was working without me executing the function on a seperate thread..

Liapo1
  • 21
  • 3
  • 2
    Does it work if you change `thread_obj.detach();` (which you probably should never ever use) to `thread_obj.join();`, does that help? – Eljay Jan 05 '22 at 17:19
  • 1
    Handy reading: [What happens to a detached thread when main() exits?](https://stackoverflow.com/questions/19744250/what-happens-to-a-detached-thread-when-main-exits) and [When should I use std::thread::detach?](https://stackoverflow.com/questions/22803600/when-should-i-use-stdthreaddetach) – user4581301 Jan 05 '22 at 17:22
  • @Eljay it does but i have to detach the thread first.. – Liapo1 Jan 05 '22 at 17:27
  • If you detach the thread first, you then need to *manually* coordinate between the spawned thread and the main thread. Otherwise the main thread will **exit the process** (which will terminate the application and all in-flight threads) possibly before the spawned thread has a chance to do anything. Making the two threads *no longer independent*, but would then be *manually coordinated and co-dependent*. Especially since the spawned thread references automatic data on the main routine's stack will that be destroyed possibly before the spawned thread has done anything yet. – Eljay Jan 05 '22 at 17:30

2 Answers2

3

The main function could end before the thread finishes, meaning the life-time of Oven ends and any references or pointers to it will become invalid.

If you don't detach the thread (and instead join it) then it should work fine.

Another solution is to use std::array instead, in which case the thread would have its own copy of the array object.


On a side-note, there's no need for std::ref here, as the dostuff function expects a pointer, not a reference. Which is what plain Oven will decay to.

Plain

std::thread thread_obj(dostuff,Oven);

would work exactly the same, and even have the same problem.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • But i have to do this on a seperate thread that works independently – Liapo1 Jan 05 '22 at 17:24
  • 1
    @Liapo1 But threads "works independently" anyway. If you start a thread, then do other work in your `main` function, you could still `join` the thread later (before the `main` function returns). The thread created earlier will still work independently from and in parallel to the `main` functions other code. – Some programmer dude Jan 05 '22 at 17:25
  • I should ask a different question then, basically im injecting a dll to a process and if i dont detach the thread represented by the object from the calling thread and not allow them to execute independently from each other(use join) the process simply freezes and it doesnt matter if the code works or not, i need to make sure it works with detach. – Liapo1 Jan 05 '22 at 17:35
  • @Liapo1 That does indeed seem worthy of another question. – Some programmer dude Jan 05 '22 at 17:54
  • Thank you so much for your answer i fixed my main problem with your std::array recommendation, do you know why default array didnt work though? – Liapo1 Jan 05 '22 at 18:31
  • @Liapo1 Arrays aren't (and without a wrapper, can't be) passed by value. Instead they *decay* to a pointer to its first element. So when you use `Oven` in a call it's the samer as `&Oven[0]`. – Some programmer dude Jan 06 '22 at 05:28
0

Because main is exiting before the threads do. Change this:

thread_obj.detach();

To be this:

thread_obj.join();
selbie
  • 100,020
  • 15
  • 103
  • 173