多线程程序经常会遇到在某个线程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指针, 指针指向的对象不会释放,即指针指向的对象不会失效, 除非所有指向此对象的指针都无效了/不用了, 此对象才会自动释放.
时间: 2024-10-13 02:13:26