C++ 独占指针被销毁后,堆也会自己销毁

独占指针被销毁后,堆也会自己销毁吗

1、结论:是的,std::unique_ptr 析构时会自动释放它托管的堆内存

unique_ptr 是独占式 RAII 智能指针 ,生命周期和托管堆对象强绑定:只要 unique_ptr 本身被销毁(出作用域、容器销毁、赋值覆盖等),它内部会自动执行 delete 释放堆上的对象。

对应你代码里的场景

cpp

运行

复制代码
// 1. 创建堆对象,task 独占持有
auto task = std::make_unique<AudioTask>();

// 2. 所有权转移到队列容器
audio_encode_queue_.push_back(std::move(task));
// 此时局部task是空(nullptr),不再管AudioTask

// 3. 编码线程取出,所有权给到局部task_ptr
auto task_ptr = std::move(audio_encode_queue_.front());
audio_encode_queue_.pop_front();

// 4. task_ptr 代码块结束、变量销毁 → 自动 delete AudioTask
// AudioTask内部的 std::vector<int16_t> pcm 会跟着自身析构,释放pcm的堆缓冲区

2、分场景细化销毁行为

场景 A:局部 unique_ptr 正常出栈

cpp

运行

复制代码
void test()
{
    auto ptr = std::make_unique<int>(100); // 堆int创建,ptr持有
} // 函数结束,ptr栈变量销毁 → 自动 delete 堆int
场景 B:容器存 unique_ptr,容器销毁

cpp

运行

复制代码
std::vector<std::unique_ptr<AudioTask>> queue;
queue.emplace_back(std::make_unique<AudioTask>());
// 程序退出/queue被销毁时,vector会逐个析构内部所有unique_ptr
// 每一个都会delete对应的AudioTask堆实例
场景 C:std::move 转移后,旧指针自动置空、不会二次释放

cpp

运行

复制代码
auto a = std::make_unique<int>(5);
auto b = std::move(a);
// a 变成空指针,a销毁时什么都不做;b持有堆内存
// b销毁时才执行delete

核心:同一堆内存永远只有一个 unique_ptr 拥有释放权,绝不会重复 delete

场景 D:手动 reset 主动释放

cpp

运行

复制代码
auto ptr = std::make_unique<AudioTask>();
ptr.reset(); // 立刻释放堆对象,ptr变为空

3、嵌套内存释放(你 AudioTask 的结构)

cpp

运行

复制代码
struct AudioTask {
    AudioTaskType type;
    uint64_t timestamp;
    std::vector<int16_t> pcm; // vector自身在AudioTask堆内存里
};
  1. unique_ptr<AudioTask> 析构 → delete AudioTask
  2. AudioTask 整体内存释放前,内部成员 pcm 先执行自身析构
  3. std::vector 析构会释放它内部存储 PCM 采样点的堆数组整条内存链全自动释放,无内存泄漏

4、对比裸指针(反例,方便理解差距)

cpp

运行

复制代码
// 裸指针不会自动释放
AudioTask* raw = new AudioTask();
// 函数结束raw栈变量销毁,堆AudioTask永远留在内存 → 内存泄漏
delete raw; // 必须手动写,忘记就漏

极简一句话记忆

unique_ptr = 自带自动 delete 的裸指针;持有者消失,堆内存同步销毁;全程独占,安全无重复释放、无泄漏。

相关推荐
Rover Ramble4 小时前
C++ 用互斥锁实现读写锁
开发语言·c++
你怎么知道我是队长5 小时前
C++零基础入门第2周:数据类型、运算符与表达式完全指南(附20段可运行代码+避坑清单)
c++
say_fall5 小时前
【Linux系统编程】Ext 文件系统:磁盘与存储、文件与目录、现代计算机究竟如何寻找文件
linux·运维·服务器·数据库·c++
雪落漂泊5 小时前
C++算法 滑动窗口篇(下)
开发语言·c++
你怎么知道我是队长8 小时前
C++零基础第3周:if/else、switch、for/while/do-while 控制流完全指南(附20段可运行代码+避坑清单)
java·开发语言·c++
青少儿编程课堂9 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:倍增法求最近公共祖先LCA解析
c++·python·算法·bfs·信息学竞赛
雷✘9 小时前
C++ 类与对象的初始化机制、成员访问边界与拷贝优化
java·网络·c++
努力实干10 小时前
简单工厂模式(Simple Factory Pattern)——C++
开发语言·c++·简单工厂模式
東隅已逝,桑榆非晚11 小时前
算法2. 双指针法-复写零
c++·笔记·学习·算法
布莱克60511 小时前
C++ 中堆和栈的区别详解
开发语言·c++·栈·堆