雖然boost.shared_ptr是個非常好的東西,使用它可以使得c++程式不需要考慮記憶體釋放的問題,但是還是有很多必須注意的地方。下面羅列了一些本人在實際工作中經常碰到的使用shared_ptr出問題的幾種情況。
1.shared_ptr多次引用同一資料,如下:
int* pint = new int[100];
boost::shared_ptrsp1(pint);
// 一些其它**之後…
boost::shared_ptrsp2(pint);
這種情況在實際中是很容易發生的,結果也是非常致命的,它會導致兩次釋放同一塊記憶體,而破壞堆。
2.使用shared_ptr包裝this指標帶來的問題,如下:
class tester
public:
tester()
~tester()
std::cout << "析構函式被呼叫!\n";
public:
boost::shared_ptrsget()
return boost::shared_ptr(this);
int main()
tester t;
boost::shared_ptrsp = t.sget(); // …
return 0;
也將導致兩次釋放t物件破壞堆疊,一次是出棧時析構,一次就是shared_ptr析構。若有這種需要,可以使用下面**。
class tester : public boost::enable_shared_from_this
public:
tester()
~tester()
std::cout << "析構函式被呼叫!\n";
public:
boost::shared_ptrsget()
return shared_from_this();
int main()
boost::shared_ptrsp(new tester);
// 正確使用sp 指標。
sp->sget();
return 0;
3.shared_ptr迴圈引用導致記憶體洩露,**如下:
class parent;
class child;
typedef boost::shared_ptrparent_ptr;
typedef boost::shared_ptrchild_ptr;
class parent
public:
~parent()
~tester() {}
// 更多的函式定義…
void fun(boost::shared_ptrsp)
// !!!在這大量使用sp指標.
boost::shared_ptrtmp = sp;
int main()
boost::shared_ptrsp1(new tester);
// 開啟兩個執行緒,並將智慧型指標傳入使用。
boost::thread t1(boost::bind(&fun, sp1));
boost::thread t2(boost::bind(&fun, sp1));
t1.join();
t2.join();
return 0;
這個**帶來的問題很顯然,由於多執行緒同是訪問智慧型指標,並將其賦值到其它同類智慧型指標時,很可能發生兩個執行緒同時在操作引用計數(但並不一定絕對發生),而導致計數失敗或無效等情況,從而導致程式崩潰,如若不知根源,就無法查詢這個bug,那就只能向上帝祈禱程式能正常執行。
可能一般情況下並不會寫出上面這樣的**,但是下面這種**與上面的**同樣,如下:
class tester
public:
tester() {}
~tester() {}
public:
boost::shared_ptrm_spdata; // 可能其它型別。
tester gobject;
void fun(void)
// !!!在這大量使用sp指標.
boost::shared_ptrtmp = gobject.m_spdata;
int main()
// 多執行緒。
boost::thread t1(&fun);
boost::thread t2(&fun);
t1.join();
t2.join();
return 0;
情況是一樣的。要解決這類問題的辦法也很簡單,使用boost.weak_ptr就可以很方便解決這個問題。第一種情況修改**如下:
class tester
public:
tester() {}
~tester() {}
// 更多的函式定義…
void fun(boost::weak_ptrwp)
boost::shared_ptrsp = wp.lock;
if (sp)
// 在這裡可以安全的使用sp指標.
else
std::cout << 「指標已被釋放!」 << std::endl;
int main()
boost::shared_ptrsp1(new tester);
boost.weak_ptrwp(sp1);
// 開啟兩個執行緒,並將智慧型指標傳入使用。
boost::thread t1(boost::bind(&fun, wp));
boost::thread t2(boost::bind(&fun, wp));
t1.join();
t2.join();
return 0;
boost.weak_ptr指標功能一點都不weak,weak_ptr是一種可構造、可賦值以不增加引用計數來管理shared_ptr的指標,它可以方便的轉回到shared_ptr指標,使用weak_ptr.lock函式就可以得到乙個shared_ptr的指標,如果該指標已經被其它地方釋放,它則返回乙個空的shared_ptr,也可以使用weak_ptr.expired()來判斷乙個指標是否被釋放。
boost.weak_ptr不僅可以解決多執行緒訪問帶來的安全問題,而且還可以解決上面第三個問題迴圈引用。children類**修改如下,即可打破迴圈引用:
class child
public:
~child() {
std::cout <<"子類析構函式被呼叫.\n";
public:
boost::weak_ptrparent;
因為boost::weak_ptr不增加引用計數,所以可以在退出函式域時,正確的析構。
公募基金可能出問題的幾種情形
今年以來 在新一輪牛市中取得了優異的投資業績,高業績背後是 投資過程中頻頻涉足高風險地帶。5月下旬再融資重起之後,公司已經投資70多億參與上市公司定向增發,定向增發鎖定期帶來的流動性風險正在考驗 公司風險控制能力。在牛市環境中 高度集中持股現象有蔓延之勢,其中,多家 公司聯合高比例重倉持有同一 的投...
shared ptr跨模組邊界的問題
如果shared ptr預設是用delete來釋放物件的,而delete動作產生的是本模組的 這在windows平台的dll中遇到了問題 可執行程式和dll分屬不同模組,分別使用各自的記憶體管理元件。直接delete,無異於把a堆管理器分配的指標讓b堆管理其去釋放,崩潰還算好的,悄悄的出錯,死都不知...
Qstring的輸出問題
有時候想在控制台輸出我們想要的qstring變數。1 qdebug可以實現在控制台終端列印,但我們還是想使用c 中的std cout this function does nothing if qt no debug output was defined during compilation.2 網...