面试题答案
一键面试问题产生原因
- 内存泄漏:
- 动态分配的内存(使用
new
或malloc
等)在程序结束前没有使用delete
或free
释放。例如在循环中不断分配内存但未释放,随着循环次数增加,占用的内存越来越多,最终耗尽系统内存资源。 - 异常处理过程中,已经分配的内存没有得到正确释放。比如在
try
块中分配内存,在catch
块中处理异常时没有释放已分配的内存。
- 动态分配的内存(使用
- 悬空指针:
- 指针所指向的内存已经被释放,但指针没有被设置为
nullptr
(在C++11及以后)或NULL
(C++11之前)。之后如果继续使用该指针,就会导致未定义行为,因为它指向的内存已经无效。 - 对象生命周期结束时,其成员指针没有被妥善处理。例如一个类的对象被销毁,但其内部的指针成员指向的内存没有释放,并且这个指针成员没有被置为
nullptr
,如果后续其他代码使用该指针成员,就会出现悬空指针问题。
- 指针所指向的内存已经被释放,但指针没有被设置为
解决方案及代码示例
- 智能指针(避免内存泄漏和悬空指针):
std::unique_ptr
:独占式拥有所指向的对象,对象生命周期由std::unique_ptr
控制。当std::unique_ptr
离开作用域时,它所指向的对象会被自动释放。
#include <iostream> #include <memory> void uniquePtrExample() { std::unique_ptr<int> ptr(new int(10)); std::cout << "Value: " << *ptr << std::endl; // 离开作用域时,内存自动释放,无需手动delete }
std::shared_ptr
:允许多个指针共享同一个对象。使用引用计数来跟踪有多少个std::shared_ptr
指向同一个对象。当引用计数为0时,对象被自动释放。
#include <iostream> #include <memory> void sharedPtrExample() { std::shared_ptr<int> ptr1(new int(20)); std::shared_ptr<int> ptr2 = ptr1; std::cout << "Value: " << *ptr2 << std::endl; // 当ptr1和ptr2离开作用域,引用计数降为0,内存自动释放 }
- RAII(Resource Acquisition Is Initialization)原则(避免内存泄漏):
- 通过在对象构造时获取资源(如分配内存),在对象析构时释放资源,将资源的生命周期与对象的生命周期绑定。
#include <iostream> class Resource { public: Resource() { data = new int(30); std::cout << "Resource acquired" << std::endl; } ~Resource() { delete data; std::cout << "Resource released" << std::endl; } int getValue() { return *data; } private: int* data; }; void raiiExample() { Resource res; std::cout << "Value: " << res.getValue() << std::endl; // res离开作用域时,自动调用析构函数释放内存 }
- 手动释放并置空指针(避免悬空指针):
- 在释放内存后,将指针设置为
nullptr
(C++11及以后)或NULL
(C++11之前)。
#include <iostream> void manualReleaseAndNullify() { int* ptr = new int(40); std::cout << "Value: " << *ptr << std::endl; delete ptr; ptr = nullptr; // 如果尝试访问ptr,会得到nullptr,而不是悬空指针导致的未定义行为 }
- 在释放内存后,将指针设置为