std::bad_weak_ptr,位於內存位置 0x0ABBF7A0 處記錄排查過程沒有解決

背景

            採用Boost asio庫發送RTP over TCP數據,調用asio::async_write(m_soc, asio::buffer(*data), std::bind(&rtsp_session::on_send, shared_from_this(), std::placeholders::_1, data, 0, std::placeholders::_2));發送數據。發送數據的過程中,客戶端中斷連接,產生10054的連接錯誤,這個時候,收到網絡異常。


分析

        網上說std::bad_weak_ptr這種錯誤是因爲在構造函數中獲取weakptr,此時對象還未構造,因此返回這樣的異常。實際上

shared_from_this()實際上已經創建對象,並且沒有銷燬,因爲沒有調用析構函數。有沒有可能是data已經釋放了,也不可能。因爲

std::shared_ptr<std::string> data = std::make_shared<std::string>((char*)rtp, rtp_size);這裏最有可能的傳參就是m_soc,因爲在背景中提及該套接字句柄在客戶端中斷的時候,調用了close函數,但問題也不應該存在該變量,因爲定義如下:asio::ip::tcp::socket m_soc


【引申】

enable_from_this 的使用與實現原理說明:
shared_from_this()是enable_shared_from_this<T>的成員函數,返回shared_ptr<T>;
注意的是,這個函數僅在shared_ptr<T>的構造函數被調用之後才能使用。
原因是enable_shared_from_this::weak_ptr並不在構造函數中設置,而是在shared_ptr<T>的構造函數中設置。


從引申中可以看出來是否是m_soc被認爲沒有初始化導致的問題,有這個可能,因爲close的時候資源已經被釋放了


使用說明

  std::enable_shared_from_this 能讓一個對象(假設其名爲 t ,且已被一個 std::shared_ptr 對象 pt 管理)安全地生成其他額外的 std::shared_ptr 實例(假設名爲 pt1, pt2, ... ) ,它們與 pt 共享對象 t 的所有權。
       若一個類 T 繼承 std::enable_shared_from_this<T> ,則會爲該類 T 提供成員函數: shared_from_this 。 當 T 類型對象 t 被一個爲名爲 pt 的 std::shared_ptr<T> 類對象管理時,調用 T::shared_from_this 成員函數,將會返回一個新的 std::shared_ptr<T> 對象,它與 pt 共享 t 的所有權。


使用原因

因爲在異步調用中,存在一個保活機制,異步函數執行的時間點我們是無法確定的,然而異步函數可能會使用到異步調用之前就存在的變量。爲了保證該變量在異步函數執期間一直有效,我們可以傳遞一個指向自身的share_ptr給異步函數,這樣在異步函數執行期間share_ptr所管理的對象就不會析構,所使用的變量也會一直有效了(保活)。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章