C++智能指针的内存布局

1. 智能指针的内存布局概述

C++ 中的智能指针如 std::shared_ptrstd::unique_ptrstd::weak_ptr,都是为了自动化内存管理,减少手动管理内存的负担。它们各自的内存布局在管理对象时有所不同,特别是涉及到多态和继承时,布局会变得更为复杂。

1.1 std::shared_ptr 的内存布局

std::shared_ptr 是引用计数智能指针,它在管理对象时会包含:

  • 控制块指针:指向控制块,用于管理引用计数、弱引用计数等信息。
  • 对象指针:指向实际的对象。

在 64 位系统上,std::shared_ptr 的内存布局大致如下:

控制块指针 (control block)对象指针 (object pointer)
8B8B
  • 控制块存储引用计数(强引用计数和弱引用计数)及其他管理信息。
  • 对象指针指向实际管理的对象。
控制块的内存布局

控制块通常会包含以下部分:

强引用计数弱引用计数其他管理信息(可选)
4B4B可能有额外的信息
  • 强引用计数:记录有多少个 shared_ptr 实例共享该对象。
  • 弱引用计数:记录有多少个 weak_ptr 引用该对象。
1.2 std::unique_ptr 的内存布局

std::unique_ptr 是独占所有权智能指针,它仅包含一个指向实际对象的指针,而不涉及引用计数,因此内存布局非常简单:

对象指针 (object pointer)
8B
  • 对象指针:指向实际管理的对象。
1.3 std::weak_ptr 的内存布局

std::weak_ptr 是观察者智能指针,它不增加引用计数,只是观察由 std::shared_ptr 管理的对象。weak_ptr 仅包含一个指向控制块的指针:

控制块指针 (control block)
8B
  • 控制块指针:指向控制块,weak_ptr 通过它来观察 shared_ptr 管理的对象,但不会增加引用计数。

2. 继承结构中的智能指针

在有继承关系的情况下,智能指针依然遵循上述内存布局,但需要考虑多态性和对象的实际类型。假设我们有以下的继承结构:

class Base {
public:
    virtual void func() {}
    int a;
};

class Derived : public Base {
public:
    void func() override {}
    double b;
};

并且使用智能指针管理这些对象:

std::shared_ptr<Base> sptr = std::make_shared<Derived>();
std::weak_ptr<Base> wptr = sptr;
std::unique_ptr<Base> uptr = std::make_unique<Derived>();
2.1 std::shared_ptr<Base> 的内存布局

std::shared_ptr<Base> 会包含以下两个指针:

  • 控制块指针:指向控制块,管理引用计数和弱引用计数等。
  • 对象指针:指向 Derived 类型对象的指针(由于多态,实际对象类型是 Derived)。

内存布局如下:

控制块指针 (control block)对象指针 (object pointer)
8B8B
2.2 std::weak_ptr<Base> 的内存布局

std::weak_ptr<Base> 只包含一个指向控制块的指针,它不会直接管理对象,也不会增加引用计数。

内存布局如下:

控制块指针 (control block)
8B
2.3 std::unique_ptr<Base> 的内存布局

std::unique_ptr<Base> 仅包含一个指向对象的指针,指向实际的 Derived 类型对象。

内存布局如下:

对象指针 (object pointer)
8B

3. 总结与对比

智能指针类型内存布局说明
std::shared_ptr控制块指针 + 对象指针shared_ptr 存储两个指针:控制块指针和指向对象的指针。
std::unique_ptr对象指针unique_ptr 仅存储原始指针,指向唯一管理的对象。
std::weak_ptr控制块指针weak_ptr 仅存储一个指向控制块的指针,不增加引用计数。
控制块强引用计数 + 弱引用计数 + 其他管理信息(可选)控制块存储引用计数、弱引用计数等信息。
  • std::shared_ptr:存储两个指针,一个指向控制块(用于管理引用计数、弱引用计数等),一个指向实际的对象。适用于多个对象共享同一资源的场景。
  • std::weak_ptr:只存储一个指向控制块的指针,不增加引用计数。它用于观察由 shared_ptr 管理的对象,解决循环引用问题。
  • std::unique_ptr:只存储原始指针,指向唯一管理的对象,确保资源独占,适用于需要单一所有权的场景。

4. 使用场景

  • std::shared_ptr:适用于多个对象共享同一资源时,可以安全地增加和减少引用计数。
  • std::weak_ptr:通常用于解决循环引用问题,它不增加引用计数,只是观察一个对象,避免对象无法被销毁。
  • std::unique_ptr:用于独占资源的场景,确保一个对象只有一个所有者。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值