JavaCV音视频同步播放实战:FFmpegFrameGrabber与声卡写入
2026/10/5 15:39:09
C++ 的内存管理是语言最核心、最容易出错、也最能体现“现代 vs 传统”差异的部分。
下面从最实用的现代 C++ 视角(C++11/14/17/20/23)来完整梳理,帮助你建立清晰的思维框架。
| 时代 | 代表写法 | 内存安全程度 | 现代项目是否推荐 | 备注 |
|---|---|---|---|---|
| C 风格时代 | new/delete/malloc/free | ★☆☆☆☆ | 几乎不推荐 | 极易泄漏、双 delete、悬垂指针 |
| 半现代时代 | auto_ptr+ 手动 new/delete | ★★☆☆☆ | 已过时 | C++98/03 时代的过渡产物 |
| 现代 C++ | RAII + 智能指针+ 容器 | ★★★★★ | 强烈推荐 | C++11 之后的主流写法 |
2025 年真实项目里,99% 的新代码应该只出现在第三行。
| 优先级 | 方式 | 所有权语义 | 典型场景 | 是否推荐 new/delete |
|---|---|---|---|---|
| 1 | 局部变量(栈上) | 作用域结束自动销毁 | 99% 的小对象、临时变量 | 绝对不写 new |
| 2 | std::unique_ptr<T> | 独占所有权 | 需要动态生命周期,但只有一个拥有者 | 推荐 make_unique |
| 3 | std::shared_ptr<T> | 共享所有权(引用计数) | 需要多处共享、延迟销毁的场景 | 推荐 make_shared |
| 4 | std::vector<T>/std::string等容器 | 容器负责 | 动态大小的序列、字符串 | 基本不用 new[] |
| 5 | std::weak_ptr<T> | 非拥有(弱引用) | 解决 shared_ptr 循环引用 | — |
| 6 | 自定义 RAII 封装类 | 资源(文件/锁/句柄) | 数据库连接、文件、互斥锁、socket 等 | — |
| 7 | 裸指针(作为观察者) | 无所有权 | 函数参数、回调、遍历(不负责释放) | 可以用,但慎用 |
// 传统写法(千万不要再这样写新代码)voidbad_style(){Widget*w=newWidget(args);// ... 可能抛异常、return、gotoif(some_condition){deletew;// 很容易漏return;}// ... 更多分支deletew;// 双 delete 风险}// 现代写法(C++14/17 之后首选)#include<memory>voidgood_style(){autow=std::make_unique<Widget>(args);// 推荐!// 或者 C++11 时代的写法(次选)// std::unique_ptr<Widget> w{new Widget(args)};// 异常安全、作用域结束自动 delete// 无需显式 delete}共享所有权场景(最常见的工厂模式)
classWidget{/* ... */};std::shared_ptr<Widget>createWidget(Params p){returnstd::make_shared<Widget>(p);// 一次分配控制块+对象,性能更好// return std::shared_ptr<Widget>(new Widget(p)); // 次选,效率稍低}| 问题 | 传统写法容易犯的错误 | 现代正确做法 |
|---|---|---|
| 内存泄漏 | 忘记 delete / 异常路径漏掉 | 用 unique_ptr / shared_ptr / 容器 |
| 悬垂指针 | 对象先销毁,指针还活着 | 用 weak_ptr + lock() 检查 |
| 双重释放 | 多次 delete | 智能指针自动管理 |
| 循环引用 | shared_ptr 互相指向 | 一方改用 weak_ptr |
| 性能浪费 | 频繁 new/delete | 用内存池、arena allocator、小对象优化 |
| 传参膨胀 | 到处传 shared_ptr | 优先用引用 / 原始指针(观察者语义) |
std::make_unique和new的主要区别是什么?为什么更推荐前者?shared_ptr而不是unique_ptr?shared_ptr<Widget>和Widget*分别代表什么语义?std::vector<Widget*>widgets;for(inti=0;i<10;i++){widgets.push_back(newWidget());}// ... 后面忘了释放如果你对其中任何一块(比如自定义分配器、enable_shared_from_this、内存池、C++20/23 新工具、性能调优等)还想深入,都可以直接告诉我,我再给你展开更具体的例子和代码。