MST

星途 面试题库

面试题:C++ 中智能指针在异常处理下的资源释放

请描述在 C++ 中使用智能指针(如 std::unique_ptr、std::shared_ptr)时,当代码块内抛出异常,智能指针是如何确保其所管理资源正确释放的?并举例说明。
32.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 智能指针确保资源正确释放的原理
    • std::unique_ptr
      • std::unique_ptr采用了RAII(Resource Acquisition Is Initialization)机制。当std::unique_ptr对象在栈上创建时,它获取资源(例如通过new操作符分配内存)。当std::unique_ptr对象离开其作用域(无论是正常结束还是因为异常),它的析构函数会被自动调用。在析构函数中,std::unique_ptr会释放其所管理的资源(例如调用delete操作符释放内存)。
    • std::shared_ptr
      • std::shared_ptr同样基于RAII机制。它通过引用计数来管理资源。当std::shared_ptr对象创建时,引用计数初始化为1。每次有新的std::shared_ptr对象指向相同的资源(例如通过拷贝构造函数或赋值操作符),引用计数增加。当std::shared_ptr对象离开其作用域(正常或因异常),引用计数减1。当引用计数变为0时,所管理的资源会被释放。
  2. 举例说明
    • std::unique_ptr示例
#include <iostream>
#include <memory>
void func() {
    std::unique_ptr<int> ptr(new int(10));
    std::cout << "Before throwing exception, value: " << *ptr << std::endl;
    throw std::runtime_error("Exception thrown");
    std::cout << "This line won't be reached" << std::endl;
}
int main() {
    try {
        func();
    } catch (const std::exception& e) {
        std::cerr << "Caught exception: " << e.what() << std::endl;
    }
    return 0;
}
  • 在上述代码中,func函数创建了一个std::unique_ptr<int>对象ptr并分配了一个int类型的内存。然后抛出一个异常。即使异常发生,std::unique_ptr的析构函数会确保分配的int内存被正确释放。
  • std::shared_ptr示例
#include <iostream>
#include <memory>
void func() {
    std::shared_ptr<int> ptr(new int(20));
    std::cout << "Before throwing exception, value: " << *ptr << std::endl;
    std::shared_ptr<int> ptr2 = ptr;
    throw std::runtime_error("Exception thrown");
    std::cout << "This line won't be reached" << std::endl;
}
int main() {
    try {
        func();
    } catch (const std::exception& e) {
        std::cerr << "Caught exception: " << e.what() << std::endl;
    }
    return 0;
}
  • 在这个代码中,func函数创建了一个std::shared_ptr<int>对象ptr并分配了一个int类型的内存。然后创建了另一个std::shared_ptr<int>对象ptr2指向相同的内存,引用计数变为2。当抛出异常时,ptrptr2离开作用域,引用计数减1变为0,所管理的int内存会被正确释放。