1. 程式人生 > 實用技巧 >shared_ptr引起記憶體洩露以及解決辦法

shared_ptr引起記憶體洩露以及解決辦法

shared_ptr如果使用不當的話,會引起記憶體洩漏。例如,對於如下定義的ClassA和ClassB

 1 class ClassA {
 2 public:
 3     ClassA() {
 4         std::cout << "ClassA()" << std::endl;
 5     }
 6 
 7     ~ClassA() {
 8         std::cout << "~ClassA()" << std::endl;
 9     }
10 
11     void setInnerPtr(shared_ptr<ClassB> pB) {
12 p = pB; 13 } 14 15 private: 16 shared_ptr<ClassB> p; 17 }; 18 19 class ClassB { 20 public: 21 ClassB() { 22 std::cout << "ClassB()" << std::endl; 23 } 24 25 ~ClassB() { 26 std::cout << "~ClassB()" << std::endl; 27 } 28
29 void setInnerPtr(shared_ptr<ClassA> pA) { 30 p = pA; 31 } 32 33 private: 34 shared_ptr<ClassA> p; 35 };

如果按照如下的方式使用這兩個類的話

1 shared_ptr<ClassA> pA = make_shared<ClassA>();
2 shared_ptr<ClassB> pB = make_shared<ClassB>();
3 
4 pA->setInnerPtr(pB);
5 pB->setInnerPtr(pA);

那麼,在離開作用域後,pA和pB的引用計數都是1,彼此都在等待對方釋放。

這個問題可以用weak_ptr解決:把ClassA和ClassB中的shared_ptr改為weak_ptr即可:

 1 class ClassA {
 2 public:
 3     ClassA() {
 4         std::cout << "ClassA()" << std::endl;
 5     }
 6 
 7     ~ClassA() {
 8         std::cout << "~ClassA()" << std::endl;
 9     }
10 
11     void setInnerPtr(shared_ptr<ClassB> pB) {
12         p = pB;
13     }
14 
15 private:
16     weak_ptr<ClassB> p;
17 };
18 
19 class ClassB {
20 public:
21     ClassB() {
22         std::cout << "ClassB()" << std::endl;
23     }
24 
25     ~ClassB() {
26         std::cout << "~ClassB()" << std::endl;
27     }
28 
29     void setInnerPtr(shared_ptr<ClassA> pA) {
30         p = pA;
31     }
32 
33 private:
34     weak_ptr<ClassA> p;
35 };

由於給weak_ptr賦值不會增加引用計數,所以,在離開作用域後,pA和pB的引用計數都是0,從而被自動釋放。

shared_ptr