C++ 内存管理进阶:从裸指针到智能指针的进化之路
在 C++ 的世界里,指针赋予了开发者直接操作内存的强大能力,但也埋下了内存泄漏、野指针、二次释放等一系列隐患。你是否曾因一个忘记释放的 new 调试了半天?是否被野指针导致的崩溃搞得怀疑人生?幸运的是,C++11 标准库提供了智能指针这套'自动驾驶'级别的解决方案,通过 RAII(资源获取即初始化)机制,让内存管理变得安全且省心。
裸指针的痛点回顾
在深入智能指针之前,先看看裸指针容易踩的坑,这也是智能指针诞生的原因。
内存泄漏
内存泄漏是指分配的内存使用完毕后未被正确释放。在复杂逻辑中,一个疏忽就可能造成泄漏。
// 反面示例:裸指针导致的内存泄漏
void func() {
int* p = new int(10);
if (some_condition) {
return; // 提前返回,忘记释放 p
}
delete p;
}
如果 some_condition 为真,函数提前返回,delete p 永远不会执行。若这段代码在循环中执行,内存会持续增长直至崩溃。
二次释放与野指针
对同一块内存多次 delete 会破坏堆完整性,导致未定义行为。而野指针指向已释放或非法地址,访问它同样危险。
// 野指针示例
int* func() {
int x = 10;
return &x; // 返回栈内存地址,函数返回后成为野指针
}
异常安全
当程序抛出异常时,正常流程被打断,裸指针可能无法到达 delete 语句。
void func() {
int* p = new int(30);
try {
throw runtime_error("error");
} catch (...) {
;
}
p;
}


