MST

星途 面试题库

面试题:C++ 智能指针与指针使用后置空操作在避免野指针上的对比与结合

在 C++ 中,智能指针已经在很大程度上解决了野指针问题。请阐述智能指针与指针使用后置空操作在避免野指针方面各自的优势和不足,并且说明在实际项目中是否可以将两者结合使用,如果可以,该如何结合?
16.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

智能指针

  • 优势
    • 自动内存管理:智能指针利用RAII(Resource Acquisition Is Initialization)机制,在对象生命周期结束时自动释放所指向的内存,无需手动调用delete,极大减少了内存泄漏的风险。例如std::unique_ptr<int> ptr(new int(10));,当ptr超出作用域时,所指向的int对象内存会自动释放。
    • 异常安全:在发生异常时,智能指针能保证已分配的资源被正确释放,避免资源泄漏。例如在函数中使用智能指针,如果函数中途抛出异常,智能指针会在析构时释放资源。
    • 简化代码:无需手动跟踪内存的分配和释放,使代码更简洁,可读性更高。
  • 不足
    • 性能开销:智能指针内部包含引用计数(如std::shared_ptr)或其他管理机制,会带来一定的性能开销,虽然通常较小,但在对性能要求极高的场景下可能成为问题。
    • 循环引用std::shared_ptr可能会出现循环引用问题,导致内存无法释放。例如两个类中都使用std::shared_ptr互相指向对方,形成循环引用,需要使用std::weak_ptr来解决。

指针使用后置空操作

  • 优势
    • 简单直接:操作简单,只需在delete指针后将指针赋值为nullptr,如int* p = new int(10); delete p; p = nullptr;,防止指针成为野指针。
    • 无额外开销:不引入额外的性能开销,仅增加了简单的赋值操作。
  • 不足
    • 手动管理:需要开发者手动进行内存释放和指针置空操作,增加了出错的可能性,容易忘记delete或置空,导致内存泄漏或野指针问题。
    • 异常不安全:如果在delete之后、置空之前抛出异常,指针仍可能成为野指针。

两者结合使用

  • 可以结合使用
    • 在实际项目中,对于一些简单的、对性能敏感且代码逻辑清晰的场景,可以在手动管理内存的指针使用后置空操作。例如在一些底层库中,对性能要求极高,且代码结构简单,手动管理内存并置空指针可避免智能指针的性能开销。
    • 对于复杂的对象层次结构、涉及动态内存分配和释放频繁的场景,优先使用智能指针。当需要从智能指针获取原始指针传递给一些不支持智能指针的API时,在使用完原始指针后,可以将其置空。例如:
std::unique_ptr<int> smartPtr(new int(10));
int* rawPtr = smartPtr.get();
// 使用rawPtr调用不支持智能指针的API
// 使用完后
rawPtr = nullptr;

这样结合可以在不同场景发挥两者的优势,减少野指针和内存泄漏的风险。