enable_shared_from_this возвращает ошибку bad_weak_ptr - PullRequest
0 голосов
/ 28 мая 2020

Я использую в своем проекте библиотеку boost. Пока я писал код клиента http для отдыха, я получил эту ошибку.

libc ++ abi.dylib: завершение с неперехваченным исключением типа std :: __ 1 :: bad_weak_ptr: bad_weak_ptr

template <typename M>
 21 class Http: public std::enable_shared_from_this<Http<M>>
 22 {
 23     M* message_;
 24     bool isSubscribe_;
 25     boost::asio::io_context io_;
 26     boost::asio::ip::tcp::resolver resolver_;
 27     boost::beast::tcp_stream stream_;
 28     boost::beast::flat_buffer buffer_;
 29     boost::beast::http::request<boost::beast::http::empty_body> req_;
 30     boost::beast::http::response<boost::beast::http::string_body> res_;
 31     std::function<void(M*)> callback_;
 32 
 33     void SetUpRestHeader() {
 34         req_.method(boost::beast::http::verb::get);
 35         req_.target(message_ -> header_ -> target_);
 36         req_.set(boost::beast::http::field::host, message_ -> header_ -> host_);
 37         req_.set(boost::beast::http::field::user_agent, BOOST_BEAST_VERSION_STRING);
 38 
 39         resolver_.async_resolve(message_ -> header_ -> host_
 40                 , message_ -> header_ -> port_
 41                 , boost::beast::bind_front_handler(
 42                     &Http::OnResolve
 43                     , this -> shared_from_this()));
 44     }
 45 

.......

128     explicit Http()
129         :io_{}
130         , resolver_(io_)
131         , stream_(io_)
132     {
133         message_ = new M;
134     }
135 
136     M RequestRestMessage()
137     {
138         auto ptr = this -> shared_from_this();
139         isSubscribe_ = false;
140         SetUpRestHeader();
141     }
142   };

151 int main()
152 {
153     Http<binance::ServerTime> http;
154     http.RequestRestMessage();
155 }

Ошибка произошла, хотя я не вызывал shared_from_this в конструкторе. Пожалуйста, поделитесь своей мудростью. Спасибо!

1 Ответ

5 голосов
/ 28 мая 2020

Если вы посмотрите на std :: enable_shared_from_this: Примеры , вы увидите это:

 // Bad: shared_from_this is called without having std::shared_ptr owning the caller 
try {
  Good not_so_good;
  std::shared_ptr<Good> gp1 = not_so_good.getptr();
} catch(std::bad_weak_ptr& e) {
  // undefined behavior (until C++17) and std::bad_weak_ptr thrown (since C++17)
  std::cout << e.what() << '\n';    
}

Ваш Http<binance::ServerTime> http; создает объект с automati c продолжительность хранения , и из-за этого он (и не должен) принадлежать shared_ptr. Ваш http.RequestRestMessage() затем выставляет this -> shared_from_this, и это причина, по которой вы получаете эту ошибку.

std :: enable_shared_from_this :: shared_from_this

Это разрешено вызывать shared_from_this только на ранее совместно используемом объекте , т.е. на объекте, управляемом std::shared_ptr (в частности, shared_from_this не может быть вызван во время построения * this).

В противном случае поведение не определено (до C ++ 17) std::bad_weak_ptr выбрасывается (конструктором shared_ptr из построенного по умолчанию weak_this) (начиная с C ++ 17).

...