Скорее всего, указанный вами объект уничтожен в точке вызова C, что указывает на проблему с синхронизацией. Вам нужно продлить время жизни объекта, на который ссылаются потоки, до тех пор, пока потоки не выполнят свою процедуру. Для этого у вас может быть что-то вроде этого:
#include <thread>
#include <array>
#include <iostream>
struct foo{
void callback1(){
for(auto & elem: storage){
elem += 5;
}
}
void callback2(){
for(const auto & elem: storage){
std::cout << elem << std::endl;
}
}
std::array<double, 300> storage;
};
int main(void){
foo f;
std::thread t1 {[&f](){f.callback1();}};
std::thread t2 {[&f](){f.callback2();}};
// wait until both threads are done executing their routines
t1.join();
t2.join();
return 0;
}
Экземпляр foo, f находится в области видимости функции main (), поэтому его время жизни определяется от строки, которую он определил, до концаосновная сфера. Присоединяясь к обоим потокам, мы препятствуем продолжению main до тех пор, пока оба потока не завершат выполнение своих функций обратного вызова, поэтому время жизни f увеличивается до тех пор, пока не будут выполнены обратные вызовы.
Вторая проблема заключается в том, что коду нужны примитивы синхронизации, потому чтопеременная хранения разделяется между двумя независимыми путями выполнения. Конечный код с правильной синхронизацией может выглядеть так:
#include <thread>
#include <array>
#include <iostream>
#include <mutex>
struct foo{
void callback1(){
// RAII style lock, which invokes .lock() upon construction, and .unlock() upon destruction
// automatically.
std::unique_lock<std::mutex> lock(mtx);
for(auto & elem: storage){
elem += 5;
}
}
void callback2(){
std::unique_lock<std::mutex> lock(mtx);
for(const auto & elem: storage){
std::cout << elem << std::endl;
}
}
std::array<double, 300> storage;
// non-reentrant mutex
mutable std::mutex mtx;
};
int main(void){
foo f;
std::thread t1 {[&f](){f.callback1();}};
std::thread t2 {[&f](){f.callback2();}};
// wait until both threads are done executing their routines
t1.join();
t2.join();
return 0;
}