通过代码分析得到智能指针的优势:
//普通指针
int *q = new int(42), *r = new int(100);
r = q;
//智能指针
auto q2 = make_shared<int>(42), r2 = make_shared<int>(100);
r2 = q2;
普通指针:
对于普通指针部分,首先分配了两个int型对象,指针分别保存在p和r中。接下来,将指针q的值赋予了r,这带来了两个非常严重的内存管理问题:
- 首先是一个直接的内存泄漏问题,r和q一样都指向42的内存地址,而r中原来保存的地址——100的内存再无指针管理,变成“孤儿内存”,从而造成内存泄漏。
- 其次是一个“空悬指针”问题。由于r和q指向同一个动态对象,如果程序编写不当,很容易产生释放了其中一个指针,而继续使用另一个指针的问题。继续使用的指针指向的是一块已经释放的内存,是一个空悬指针,继续读写它指向的内存可能导致程序崩溃甚至系统崩溃的严重问题。
智能指针:
shared_ptr则可很好地解决这些问题。首先,分配了两个共享的对象,分别由共享指针q2和r2指向,因此它们的引用计数均为1。接下来,将q2赋予r2。赋值操作会将q2指向的对象地址赋予r2,并将r2原来指向的对象的引用计数减1,将q2指向的对象的引用计数加1。这样,前者的引用计数变为0,其占用的内存空间会被释放,不会造成内存泄漏。而后者的引用计数变为2,也不会因为r2和q2之一的销毁而释放它的内存空间,因此也不会造成空悬指针的问题。