C++智能指针shared_ptr之别名构造函数(aliasing constructor)

本文详细解析了智能指针`shared_ptr`的工作原理及其在内存管理中的应用,通过实例展示了如何通过别名构造函数共享对象,并探讨了`reset()`函数对对象所有权的影响。在示例中,由于未正确释放`newPerson`创建的对象,导致了内存泄漏问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

别名构造函数,sp也成了sp2的共享对象的拥有者,但sp却指向ptr

shared_ptr<T> sp(sp2,ptr);

在讲解别名构造函数前,了解一下shared_ptr的机制

shared_ptr由两个指针构成, 为便于描述,简称其中一个是 控制块指针,另一个是存储指针。当引用计数为0时,会释放控制块指针指向的堆区内存,但不会释放存储指针指向的堆区内存.。一般情况下,控制块指针和存储指针指向的是同一块堆区内存(刚刚说明的机制恰好能够保证同一块堆区内存不会被多次释放)。

class Person {
public:
	Person(int n):name(n){}
	~Person() {
		cout << “Person的析构 ”<<name << endl;
	}
	int name;

};
int main() {
  //第一部分
	shared_ptr<Person> sp1{ new Person(5) };//sp1是共享对象(也就是new出来的Person)的唯一拥有者
	shared_ptr<Person> sp2{ sp1,new Person(6) };//现在sp1,sp2都是共享对象的拥有者
	cout << sp1.use_count() <<", "<< sp2.use_count()<< endl; //2,2 
	       //请注意:调用sp1.use_count,如果sp1不拥有任何共享对象,返回0。
	       //如果拥有共享对象,返回的是该共享对象的拥有者的总数
	
	//第二部分
	sp1.reset(); //reset会让sp1放弃对共享对象的所有权并重新初始化,sp1的控制区指针被置空。
	             //现在sp2成了共享对象的唯一拥有者
	cout << sp1.use_count() << ", " << sp2.use_count() << endl; //0,1
	shared_ptr<Person> sp3{ sp1,new Person(7) };//因为sp1已经不拥有任何共享对象,导致sp3也没有
	cout << sp3.use_count() <<  endl; //0
	cout << sp1.use_count() << ", " << sp2.use_count() << endl;//0,1
    if (sp3.get() == nullptr)  //因为get返回的是存储指针,所以这里为false
		cout << "sp3的存储指针已置空" << endl;
	
	//第三部分
	sp3.reset();
	if (sp3.get() == nullptr)  //为true,说明reset不仅能够置空控制区指针
	                           //还可以置空存储指针
		cout << "sp3的存储指针已置空" << endl;
return 0;
}//结尾输出: Person的析构 5
 //注:当共享对象的唯一拥有者sp2销毁时,引用计数由1变为0(即共享对象现在没有任何人拥有它了),
 //进而调用Person的析构函数
 

根据结果可知:new Person(6)、new Person(7)所创建的堆区空间,都没有被释放,造成内存泄漏

下面是上述程序第一部分的图解:

在这里插入图片描述

第二部分的图解:

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值