The following abstraction model is used:
//SHP_*** обозначены shared_ptr<***> class A { std::vector<SHP_B> vecB; boost::asio::io_service io; } class B { B(...){socket = std::make_shared<Socket>(...);} ~B(){socket->s.close();} private: SHP_Socket socket; } class Socket { Socket(...){s.open(...); s.set_option(...); s.bind(...);} boost::asio::ip::udp::socket s; } All these classes and their implementation are in different files. Everything is going perfectly, it works, it is initialized, the sockets are sending data. vecB are added and removed in vecB ... Until I call the class А destructor. In this case, the vecB must contain (and contains, checked) 2 elements SHP_B .
Then a memory access error occurs: Unhandled exception at 0x77BE57DA (ntdll.dll) in Conference.exe: 0xC0000005: Access violation reading location 0xFEEEFEF6. and debager throws to the file: ...\boost\asio\detail\impl\win_iocp_socket_service_base.ipp
void win_iocp_socket_service_base::destroy( win_iocp_socket_service_base::base_implementation_type& impl) { close_for_destruction(impl); // Remove implementation from linked list of all implementations. boost::asio::detail::mutex::scoped_lock lock(mutex_); if (impl_list_ == &impl) // <- дебагер указывает на эту строчку impl_list_ = impl.next_; if (impl.prev_) impl.prev_->next_ = impl.next_; if (impl.next_) impl.next_->prev_= impl.prev_; impl.next_ = 0; impl.prev_ = 0; } I understand that the error is caused by an attempt to delete an already deleted socket or an attempt to delete an open socket (which is unlikely), but why? I call closing the socket only in ~B() , which, after execution, should also call the Socket class destructor, in which the destructor is called for boost::asio::ip::udp::socket s ., Tried to close it manually and remove the elements from vecB one by one before calling the default destructor for class А (after all, before I need to remove an object from A worked fine ...). I tried to transfer the closure of the socket to ~Socket() - it did not help.
What caused this problem and how to solve it?
boost::asio::io_service ioout of class. Those. so that he lived after the destruction ofA- αλεχολυτio_servicefor each object fromАand it is not convenient to store them separately. Therefore, thanks to your tip, I added a~A()cleaningvecBbefore the automatic destructorA~A(). - Dmitry