C++11 shared_ptr 智能指針 的使用,避免內存泄露


     多線程程序經常會遇到在某個線程A創建了一個對象,這個對象需要在線程B使用,

在沒有shared_ptr時,因為線程A,B結束時間不確定,即在A或B線程先釋放這個對象都有可能造成另一個線程崩潰,

所以為了省時間一般都是任由這個內存泄漏發生.

當然也可以經過復雜的設計,由一個監控線程來統一刪除,

但這樣會增加代碼量和復雜度.這下好了,shared_ptr 可以方便的解決問題,因為它是引用計數和線程安全的.

shared_ptr不用手動去釋放資源,它會智能地在合適的時候去自動釋放。

我們來測試看看效果

 1 //C++11 shared_ptr 智能指針 的使用,避免內存泄露
 2 #include <iostream>
 3 #include <memory>
 4 using namespace std;
 5 
 6 #define _PRT(T) std::shared_ptr<T>
 7 
 8 //定義 shared_ptr<T> 的智能指針
 9 #define _PRTO(T,N,...)  std::shared_ptr<T> N(new T(##__VA_ARGS__))
10 
11 //定義 shared_ptr<T> 的數組智能指針
12 #define _PRTA(T,N,n)    std::shared_ptr<T> N(new T[n])
13 
14 class A {
15 public:
16     int n;
17     A(int n):n(n) {
18         cout <<n<< " construct A!!!" << endl;
19     }
20     ;
21     ~A() {
22         cout <<n<< " destruct A!!!" << endl;
23     }
24     ;
25     void Out(){ cout << n * 2 << endl; }
26 };
27 class B : public A {
28 public:
29     B(int n):A(n) {
30         cout <<n<< " construct B!!!" << endl;
31     }
32     ;
33     ~B() {
34         cout <<n<< " destruct B!!!" << endl;
35     }
36     ;
37     _PRT(A) geta(int n) { _PRTO(A,a,n); return a; }
38 
39     void chars() {
40         //使用智能指針指向 char[],以自動釋放
41         _PRTA(char,p,1024*1024);
42         strcpy(p.get(), "std::shared_ptr<char*>");
43         printf(p.get());
44     }
45     
46 };
47 int main() {
48     B* ptrB0 = new B(1);
49     ptrB0->Out();
50 
51     _PRT(B) ptrB1(new B(2));
52     ptrB1->Out();
53     _PRT(A) a = ptrB1->geta(5);
54     a->Out();
55     //復制了指針,增加引用計數
56     _PRT(B) ptrB2 = ptrB1;57     _PRT(A) b = ptrB2->geta(6);
58     b->Out();
59     ptrB2->Out();
60 
61     //使用智能指針,會自動釋放
62     for(int i=100;i;i--)
63         ptrB2->chars();
64 }

 

測試程序中循環了100次,每次 new 了1Mb的內存, 調試過程中可以看到每次循環完內存都沒有增長;

並且main執行完后,直接new的 類1 沒有釋放, 而類2自動釋放了,

並且 如果有賦值給其他shared_ptr指針, 指針指向的對象不會釋放,即指針指向的對象不會失效, 除非所有指向此對象的指針都無效了/不用了, 此對象才會自動釋放.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM