面试题答案
一键面试常见指针操作引发内存泄漏场景
void memoryLeakExample() {
int* ptr = new int(5);
// 这里没有delete ptr,函数结束时ptr指向的内存无法释放,造成内存泄漏
}
在上述代码中,new
分配了一块内存,但没有使用delete
释放,当函数结束,指针ptr
超出作用域,导致其指向的内存无法被回收。
使用智能指针避免内存泄漏
- 使用
std::unique_ptr
#include <memory>
void useUniquePtr() {
std::unique_ptr<int> ptr(new int(5));
// 函数结束时,std::unique_ptr的析构函数会自动释放内存
}
std::unique_ptr
采用独占式所有权,同一时刻只有一个std::unique_ptr
可以指向给定对象。当std::unique_ptr
被销毁时,它所指向的对象也会被销毁。
- 使用
std::shared_ptr
#include <memory>
void useSharedPtr() {
std::shared_ptr<int> ptr1(new int(5));
std::shared_ptr<int> ptr2 = ptr1; // ptr1和ptr2共享指向的对象
// 当ptr1和ptr2都超出作用域时,引用计数降为0,对象被释放
}
std::shared_ptr
采用引用计数的方式管理对象。多个std::shared_ptr
可以指向同一个对象,每当有新的std::shared_ptr
指向该对象,引用计数增加;当一个std::shared_ptr
被销毁,引用计数减少。当引用计数降为0时,对象被释放。
智能指针内存管理策略差异
- 所有权
std::unique_ptr
具有独占所有权,对象只能由一个std::unique_ptr
管理。std::shared_ptr
允许多个指针共享对象的所有权。
- 内存释放时机
std::unique_ptr
在其析构时释放对象内存。std::shared_ptr
在引用计数为0时释放对象内存,即最后一个指向对象的std::shared_ptr
被销毁时。
- 性能开销
std::unique_ptr
几乎没有额外的运行时开销,因为它不需要维护引用计数。std::shared_ptr
由于需要管理引用计数,有一定的额外开销,包括引用计数的增减操作以及可能的线程同步开销(如果在多线程环境下使用)。