智能指针是如何知道内存释放的时机的

1.概要

1.要点

智能指针的理解,其实承载智能指针的对象,就是一个正常的对象,正常的非指针对象,是被系统自动管理的,只不过当自己被释放的时候他选择是否释放自己关联的内存;

 2.相关链接

智能指针处理char*的数据-优快云博客

关于字节数组的内存清理(delete和delete[ ])-优快云博客

智能指针管理char*数据的内存释放-优快云博客 

智能指针是如何知道内存释放的时机的-优快云博客

2.内容

智能指针通过引用计数机制来自动管理内存的释放时机。具体来说,智能指针会在以下几种情况下自动释放内存:

  1. 超出作用域
    • 当智能指针对象超出其作用域时,其析构函数会被调用。析构函数会检查引用计数,如果引用计数为0,则释放所管理的内存。
  2. 显式销毁
    • 可以使用 reset() 方法显式销毁智能指针。当调用 reset() 方法时,智能指针会检查引用计数,如果引用计数为0,则释放所管理的内存。
  3. 引用计数为0
    • 对于 std::shared_ptr,当最后一个拥有该对象的智能指针被销毁或重置时,引用计数会减为0,此时智能指针会释放所管理的内存。

智能指针内部通常包含两个指针:

  1. 指向对象的指针:这是实际存储数据的指针。
  2. 指向控制块的指针:控制块中包含了引用计数和其他可能的元数据。引用计数用于跟踪当前有多少个智能指针实例指向该对象。

当智能指针被复制或赋值时,控制块中的引用计数会增加。当智能指针被销毁或重置时,引用计数会减少。当引用计数变为0时,智能指针会知道是时候释放所管理的内存了。

以下是一个简化的示例,展示了智能指针如何通过引用计数机制来管理内存的释放时机:

#include <memory>
#include <iostream>

void foo() {
    // 使用 std::shared_ptr 管理动态分配的内存
    std::shared_ptr<int> ptr1 = std::make_shared<int>(42);

    // 此时引用计数为 1
    std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl; // 输出 1

    // 复制 ptr1,引用计数增加
    std::shared_ptr<int> ptr2 = ptr1;
    std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl; // 输出 2
    std::cout << "ptr2 use count: " << ptr2.use_count() << std::endl; // 输出 2

    // 离开作用域,ptr2 被销毁,引用计数减少
    // 此时引用计数为 1,内存不会被释放

    // 再次离开作用域,ptr1 被销毁,引用计数变为 0
    // 智能指针会自动释放所管理的内存
}

int main() {
    foo();
    // 在 foo() 函数结束后,ptr1 和 ptr2 都超出了作用域
    // 引用计数变为 0,内存被释放

    return 0;
}

在这个例子中,当 foo() 函数结束时,ptr1 和 ptr2 都超出了作用域。此时,它们的析构函数会被调用,引用计数会减为0,智能指针会自动释放所管理的内存。

3.关联知识

1.c++ 智能指针内存需要自己释放吗

在 C++ 中,智能指针(Smart Pointer)的主要目的之一就是自动管理内存,从而避免手动释放内存的麻烦和潜在的内存泄漏问题。常见的智能指针类型包括 std::unique_ptr 和 std::shared_ptr

  1. std::unique_ptr

    • std::unique_ptr 是一种独占所有权的智能指针。当 std::unique_ptr 离开作用域或被销毁时,它所管理的内存会自动释放。
    • 由于 std::unique_ptr 不允许指针的复制(只允许移动),因此确保了内存块有且仅有一个所有者。

    示例:

    #include <memory>
    
    void foo() {
        std::unique_ptr<int> ptr = std::make_unique<int>(42);
        // 不需要手动释放内存,当 ptr 离开作用域时会自动释放
    }
  2. std::shared_ptr

    • std::shared_ptr 是一种共享所有权的智能指针。多个 std::shared_ptr 实例可以共享同一个内存块。
    • 当最后一个 std::shared_ptr 离开作用域或被销毁时,它所管理的内存会自动释放。
    • std::shared_ptr 使用引用计数来管理内存块的生命周期。

    示例:

    #include <memory>
    
    void foo() {
        std::shared_ptr<int> ptr1 = std::make_shared<int>(42);
        std::shared_ptr<int> ptr2 = ptr1; // 共享同一个内存块
        // 不需要手动释放内存,当最后一个 shared_ptr 离开作用域时会自动释放
    }
  3. std::weak_ptr

    • std::weak_ptr 是一种弱引用,不能独立拥有内存块,通常用于解决 std::shared_ptr 的循环引用问题。

总结:

  • 使用智能指针(如 std::unique_ptr 和 std::shared_ptr)后,你不需要手动释放内存。智能指针会在适当的时候自动释放所管理的内存。
  • 手动管理内存(例如使用 new 和 delete)容易出错,容易导致内存泄漏或未定义行为,因此推荐使用智能指针来管理动态内存。

希望这能解答你的疑问!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值