shared ptr的注意點

2021-09-02 01:32:16 字數 1801 閱讀 8591

對於c++新手而言,面對複雜的專案中指標的四處傳遞,或者異常後的處理,很容易引起申請了記憶體沒有釋放的問題,c++11給出了智慧型指標來簡化這一問題,常用的是shared_ptr。shared_ptr構造出的物件來管理一塊記憶體,結構如下:

其中ptr指向了一塊記憶體空間,ret_count儲存了有多少shared_ptr物件引用了這塊記憶體。當引用計數為0時,刪除這塊記憶體。但是使用它如果用的不恰當,也會引發一些問題,我個人覺得,如果要使用shared_ptr,那就全部用它,不要再用裸指標 。因為裸指標不是通過shared_ptr物件的傳遞那就不會改變它的引用計數。 比如下面的**:

int *q;

在區域性作用域結束後,其實兩個shared_ptr的引用計數都為1,所以就會呼叫兩次delete,就會引發異常。

shared_ptr中有乙個get函式,可以獲得其原始指標,但我覺得get後最好不要賦值給其他指標,否則可能會寫出下面的**:

shared_ptrp = make_shared(42);

cout << *p;

int *q = p.get();

// 程式塊結束,q被銷毀,指向的記憶體被釋放。

cout << *p;//此時p記憶體已被釋放,此處引用乙個野指標會異常

在區域性作用域中sp引用計數為1,結束後銷毀q指向的記憶體,q是p的get獲得,所以就是釋放的p的記憶體,此時再訪問p就會出問題。

類似的,還有下面的情況,不要將get後的指標在reset中引用

第三行**處sp呼叫reset後會刪除sp本身所在的記憶體,然後引用sp2的記憶體,輸出時*sp與*sp2都為20,但是由於通過get方法構造的,他們的use_count都為1,所以在程式塊結束時分別呼叫delete又會刪除同一塊記憶體兩次。

另外就是迴圈引用問題

引用其他文章的一段**

class parent;

class children;

typedef shared_ptrparent_ptr;

typedef shared_ptrchildren_ptr;

class parent

public:

//weak_ptrchildren;

children_ptr children;

};class children

public:

parent_ptr parent;

//weak_ptrparent;

};void test()

void main()

原文:

由於father類中持有son類的shared_ptr,son類中也持有father類的shared_ptr,導致在作用域結束時引用計數都為2,引起記憶體洩露,解決辦法就是將成員變數改為weak_ptr,week_ptr專門為了配合shared_ptr而生,它不修改引用計數,可通過expired函式檢查是否有效。

最後就是在多執行緒下的問題,shared_ptr的引用計數本身是安全且無鎖的。但是對於讀寫則需要加鎖,引用一段**:

shared_ptrglobal_instance = make_shared(0);

std::mutex g_i_mutex;

void thread_fcn()}

int main(int argc, char** argv)

ExecuteNonQuery 的注意點

最近忙個專案,在查詢某個表中是否有資料的時候,我用了executenonquery 並通過判斷值是否大於0來判斷資料的存在與否。結果與我所設想的很不一致,除錯時才發現,其執行後返回的結果是 1,對此我很是不理解,回頭查了下資料,如下顯示 sqlcommand.executenonquery 方法對連...

UITextView的注意點

cell.label.text 會議介紹 cell.text text 2015年,德州儀器為推動中國創新半導體技術的發展,幫助工程師提高生產力並激發新設計。特邀請國內頂尖專家在全國舉辦技術培訓研討會,與您分享最新的研發案例和堵門設計技巧,為您提供最前沿的積水昂街和深度剖析沒在培訓中,阿三搜尋空間開...

readLine 的注意點

我在做csv檔案匯入匯出時用了bufferedreader,用起來挺方便的。bufferedreader br new bufferedreader new inputstreamreader socket.getinputstream string line while line br.readl...