Использование std:: async ломает мою программу где-то еще, чтение нарушения доступа
Я работаю над приложением MFC, написанным на visual C++ в visual studio 2015. Я вызываю функцию объекта, используя указатель на него. Я получаю исключение "нарушение доступа чтения местоположения 0x4a522c31" здесь:
void Handler::NotifyEvent(I_Handler::eNotification nNotification){ for (t_InterfaceList::const_iterator iter = m_oClientList.begin(); iter != m_oClientList.end(); iter++){ (*iter)->I_Handler_OnEvent(nNotification); } }
Полное сообщение об ошибке выглядит следующим образом: исключение, вызванное в 0x6ce42dc6 (ucrtbase.dll) в program.exe: 0xc000005: нарушение доступа к местоположению чтения 0x4a522c31. Это происходит при вызове функции I_Handler_OnEvent ().
Обработчик класса таков:
class Handler{ typedef list<I_Handler*> t_InterfaceList; t_InterfaceList m_oClientList; static Handler* GetInstance(); bool AddClient(I_Handler * pInterface); bool RemoveClient(I_Handler * pInterface); void OnTimer(); void NotifyEvent(I_Handler::eNotification nNotification); }
Класс I_Handler таков:
class I_Handler { public: virtual void I_Handler_OnEvent(eNotification nNotification) = 0; };
Программное обеспечение работает следующим образом:
- Обработчик класса имеет список клиентов, которые относятся к классу I_Handler.
- Когда что-то происходит внутри OnTimer(), клиенты должны быть уведомлены.
- Чтобы уведомить их, внутри OnTimer() вызывается функция NotifyEvent ().
- NotifyEvent () перебирает список клиентов и вызывает каждую функцию I_Handler_OnEvent()
У меня есть класс где-то еще, который управляет окном (это CFormView), и он также является клиентом обработчика, что означает, что этот класс является чем-то вроде этого:
class View_Control : public CFormView, public I_Handler{ DECLARE_DYNCREATE(View_Control) protected: View_Control(); virtual ~View_Control(); public: void I_Handler_OnEvent(eNotification nNotification) override; }
std:: async используется для параллельного запуска задач в различных функциях внутри обработчика класса. Внутри функции OnTimer() Я проверяю готовность задачи с помощью wait_for для будущего объекта, возвращаемого std:: async. Когда я получаю std:: future_status:: ready, я вызываю NotifyEvent (), и все падает. Обратите внимание, что если я закомментирую вызов std::async, то задача не будет запущена и NotifyEvent() будет работать так, как задумано.
Что я уже пробовал:
Я проверил, и адрес указателя правильный, он указывает на объект класса 'View_Control', который зарегистрировался как клиент.
'AddClient' вызывается внутри функции ControlView, например:
Обработчик:: GetInstance () - >AddClient(this). Я проверил это и *iter, они всегда имеют разные значения, но близки (в одном исполнении *iter был 0x00595E78, а это было 0x00595DA8. Однако исключение всегда происходит при чтении одного и того же адреса, который нигде не находится рядом с этими указателями.
Похоже, что тот факт, что функция выполняется в другом потоке, созданном std::async, нарушает способность NotifyEvent() вызывать функцию-член указателем на объект.
Почему это происходит?