内存管理基础
C++的内存管理分为栈(Stack)和堆(Heap)。栈由编译器自动分配释放,存储局部变量和函数调用信息;堆通过手动分配(new/delete或malloc/free)管理,生命周期由程序员控制。
- 栈内存:高效但空间有限,超出容量导致栈溢出。
- 堆内存:灵活但需手动管理,不当使用易引发内存泄漏或野指针。
动态内存分配
使用new和delete操作符:
cpp
int* ptr = new int(42); // 分配一个int并初始化为42
delete ptr; // 释放内存
数组分配需匹配new[]和delete[]:
cpp
int* arr = new int[10]; // 分配10个int的数组
delete[] arr; // 释放数组
智能指针
C++11引入智能指针自动管理堆内存:
-
unique_ptr:独占所有权,不可复制,移动语义转移所有权。cppstd::unique_ptr<int> uptr(new int(10)); -
shared_ptr:引用计数,多个指针共享所有权。cppstd::shared_ptr<int> sptr = std::make_shared<int>(20); -
weak_ptr:解决shared_ptr循环引用问题,不增加引用计数。
内存泄漏检测
- 工具:Valgrind、AddressSanitizer(ASan)等。
- 编码习惯:优先使用智能指针,避免裸指针;RAII(资源获取即初始化)封装资源。
自定义内存管理
重载new和delete实现定制分配策略:
cpp
void* operator new(size_t size) {
void* ptr = custom_alloc(size);
if (!ptr) throw std::bad_alloc();
return ptr;
}
void operator delete(void* ptr) noexcept {
custom_free(ptr);
}
性能优化
- 内存池:预分配大块内存减少频繁分配开销。
- 对齐分配 :使用
alignas或平台特定API(如posix_memalign)提升访问效率。
常见陷阱
- 悬垂指针:释放后未置空,后续访问导致未定义行为。
- 双重释放:同一内存多次释放引发崩溃。
- 类型不匹配 :
new[]与delete混用导致未定义行为。
通过合理选择栈/堆、善用智能指针和工具检测,可高效安全地管理C++内存,充分发挥其性能优势。