C++裡可能出現的記憶體問題:
- 緩沖區溢出 : 用 vector 或 string 管理緩沖區,并通過成員函數而不是裸指針修改緩沖區
- 空懸指針/野指針:用 shar_ptr / weak_ptr
- 重複釋放:用 scoped_ptr,隻在對象析構的時候釋放一次
- 記憶體洩漏:用 scoped_ptr,對象析構的時候自動釋放記憶體
- 不配對的new[]/delete:把 new[] 通通換為 vector / scoped_array
- 記憶體碎片
shared_ptr用法小結
-
意外延長對象的生命周期
使用 bind 綁定了一個 share_ptr指向的一個函數或成員函數
- 線程安全問題:
- 不同的shared_ptr即使綁定了相同的對象也是線程安全的
- 對同一shared_ptr任何操作線程不安全
-
傳遞shared_ptr對象的技巧
shared_ptr< T >p;
- 若直接傳遞 f ( p ) ,由于線程安全問題,傳遞之前要加鎖,但由于是同步調用過程,加鎖後要等調用函數執行完再解鎖,這樣的效率太低
- 可以先加鎖對 shared_ptr 拷貝後解鎖,傳遞拷貝後的值,利用const &接收,減少一次拷貝(因為shared_ptr的拷貝需要改變引用計數,導緻拷貝的代價要比普通指針高,是以盡量不拷貝)
-
析構動作在建立時捕獲
對象的析構是同步的,當最後一個指向 x 的 shared_ptr 離開其作用域的時候,x 會同時在同一個線程析構,這個線程不一定是對象誕生的線程。如果對象的析構比較耗時,那麼可能會拖慢關鍵線程的速度。我們可以用一個單獨的線程專門做析構,通過一個BlockingQueue< shared_ptr >把對象的析構都轉移到專用線程,進而解放關鍵線程
-
注意避免循環引用
通常的做法是 owner 持有指向 child 的 shared_ptr,child 持有指向 owner 的 weak_ptr
-
enable_shared_from_this
類 T 通過繼承 enable_shared_from_this< T >,可以通過 shared_from_this() 傳回shared_ptr 共享目前執行個體的所有權( 為了使用shared_from_this() ,object 不能是stack object ,必須是 heap object 且由shared_ptr 管理其生命期 )