當前位置:首頁 > 公眾號精選 > C語言與CPP編程
[導讀]很多人談到c++,說它特別難,可能有一部分就是因為c++的內存管理吧,不像java那樣有虛擬機動態(tài)的管理內存,在程序運行過程中可能就會出現(xiàn)內存泄漏,然而這種問題其實都可以通過c++11引入的智能指針來解決,相反我還認為這種內存管理還是c++語言的優(yōu)勢,因為盡

很多人談到c++,說它特別難,可能有一部分就是因為c++的內存管理吧,不像java那樣有虛擬機動態(tài)的管理內存,在程序運行過程中可能就會出現(xiàn)內存泄漏,然而這種問題其實都可以通過c++11引入的智能指針來解決,相反我還認為這種內存管理還是c++語言的優(yōu)勢,因為盡在掌握。

c++11引入了三種智能指針:

  • std::shared_ptr

  • std::weak_ptr

  • std::unique_ptr

shared_ptr

shared_ptr使用了引用計數(shù),每一個shared_ptr的拷貝都指向相同的內存,每次拷貝都會觸發(fā)引用計數(shù)+1,每次生命周期結束析構的時候引用計數(shù)-1,在最后一個shared_ptr析構的時候,內存才會釋放。

使用方法如下:

struct ClassWrapper { ClassWrapper() {        cout << "construct" << endl; data = new int[10]; }    ~ClassWrapper() { cout << "deconstruct" << endl; if (data != nullptr) { delete[] data; } } void Print() { cout << "print" << endl; } int* data;};
void Func(std::shared_ptr<ClassWrapper> ptr) {    ptr->Print();}
int main() { auto smart_ptr = std::make_shared<ClassWrapper>(); auto ptr2 = smart_ptr; // 引用計數(shù)+1 ptr2->Print(); Func(smart_ptr); // 引用計數(shù)+1 smart_ptr->Print(); ClassWrapper *p = smart_ptr.get(); // 可以通過get獲取裸指針 p->Print(); return 0;}

智能指針還可以自定義刪除器,在引用計數(shù)為0的時候自動調用刪除器來釋放對象的內存,代碼如下:

std::shared_ptr<int> ptr(new int, [](int *p){ delete p; });

關于shared_ptr有幾點需要注意:

? 不要用一個裸指針初始化多個shared_ptr,會出現(xiàn)double_free導致程序崩潰

? 通過shared_from_this()返回this指針,不要把this指針作為shared_ptr返回出來,因為this指針本質就是裸指針,通過this返回可能 會導致重復析構,不能把this指針交給智能指針管理。

class A { shared_ptr<A> GetSelf() { return shared_from_this(); // return shared_ptr<A>(this); 錯誤,會導致double free } };
  • 盡量使用make_shared,少用new。

  • 不要delete get()返回來的裸指針。

  • 不是new出來的空間要自定義刪除器。

  • 要避免循環(huán)引用,循環(huán)引用導致內存永遠不會被釋放,造成內存泄漏。

using namespace std;struct A;struct B;
struct A { std::shared_ptr<B> bptr; ~A() { cout << "A delete" << endl; }};
struct B { std::shared_ptr<A> aptr; ~B() { cout << "B delete" << endl; }};
int main() { auto aaptr = std::make_shared<A>(); auto bbptr = std::make_shared<B>(); aaptr->bptr = bbptr; bbptr->aptr = aaptr; return 0;}

上面代碼,產生了循環(huán)引用,導致aptr和bptr的引用計數(shù)為2,離開作用域后aptr和bptr的引用計數(shù)-1,但是永遠不會為0,導致指針永遠不會析構,產生了內存泄漏,如何解決這種問題呢,答案是使用weak_ptr。

weak_ptr

weak_ptr是用來監(jiān)視shared_ptr的生命周期,它不管理shared_ptr內部的指針,它的拷貝的析構都不會影響引用計數(shù),純粹是作為一個旁觀者監(jiān)視shared_ptr中管理的資源是否存在,可以用來返回this指針和解決循環(huán)引用問題。

  • 作用1:返回this指針,上面介紹的shared_from_this()其實就是通過weak_ptr返回的this指針,這里參考我之前寫的源碼分析shared_ptr實現(xiàn)的文章,最后附上鏈接。

  • 作用2:解決循環(huán)引用問題。

struct A;struct B;
struct A { std::shared_ptr<B> bptr; ~A() { cout << "A delete" << endl; } void Print() { cout << "A" << endl; }};
struct B { std::weak_ptr<A> aptr; // 這里改成weak_ptr ~B() { cout << "B delete" << endl; } void PrintA() { if (!aptr.expired()) { // 監(jiān)視shared_ptr的生命周期 auto ptr = aptr.lock(); ptr->Print(); } }};
int main() { auto aaptr = std::make_shared<A>(); auto bbptr = std::make_shared<B>(); aaptr->bptr = bbptr; bbptr->aptr = aaptr; bbptr->PrintA(); return 0;}輸出:AA deleteB delete

unique_ptr

std::unique_ptr是一個獨占型的智能指針,它不允許其它智能指針共享其內部指針,也不允許unique_ptr的拷貝和賦值。使用方法和shared_ptr類似,區(qū)別是不可以拷貝:

using namespace std;
struct A { ~A() { cout << "A delete" << endl; } void Print() { cout << "A" << endl; }};

int main() { auto ptr = std::unique_ptr<A>(new A); auto tptr = std::make_unique<A>(); // error, c++11還不行,需要c++14 std::unique_ptr<A> tem = ptr; // error, unique_ptr不允許移動 ptr->Print(); return 0;}

unique_ptr也可以像shared_ptr一樣自定義刪除器,使用方法和shared_ptr相同。

關于c++11的智能指針的使用就介紹到這里,大家有問題可以點此留言 ,我會盡快回復~

參考資料

https://www.jianshu.com/p/b6ac02d406a0
https://juejin.im/post/5dcaa857e51d457f7675360b#heading-16
《深入應用c++11:代碼優(yōu)化與工程級應用》

免責聲明:本文內容由21ic獲得授權后發(fā)布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產業(yè)博覽會開幕式在貴陽舉行,華為董事、質量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經營業(yè)績穩(wěn)中有升 落實提質增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉