MST

星途 面试题库

面试题:C++类析构函数在异常处理中的自动调用情况

已知代码片段:class Resource { public: Resource() { std::cout << "Resource acquired" << std::endl; } ~Resource() { std::cout << "Resource released" << std::endl; } }; void func() { Resource res; throw std::runtime_error("Some error"); } int main() { try { func(); } catch(...) { std::cout << "Exception caught" << std::endl; } return 0; } 分析析构函数的调用过程,若将`Resource res;`改为`Resource* res = new Resource();`,且在`func`函数末尾不手动`delete res;`,析构函数的调用情况会发生什么变化?为什么?
40.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 原始代码Resource res;时析构函数调用过程
    • 当进入func函数,执行Resource res;时,调用Resource的构造函数,输出Resource acquired
    • 当执行到throw std::runtime_error("Some error");时,由于异常抛出,栈展开。func函数中的局部变量res的生命周期结束,调用Resource的析构函数,输出Resource released
    • 然后在main函数的try - catch块中捕获到异常,输出Exception caught
  2. 改为Resource* res = new Resource();且不手动delete res;时析构函数调用情况及原因
    • 调用情况:Resource的析构函数不会被调用。
    • 原因:当执行Resource* res = new Resource();时,在堆上分配了内存并调用Resource的构造函数,输出Resource acquired。当执行throw std::runtime_error("Some error");时,异常抛出,栈展开。但是res是一个指针,它是栈上的局部变量,其生命周期结束时,只是指针本身被销毁,而指针指向的堆上的Resource对象并没有被释放,因为没有调用delete res;。所以Resource的析构函数不会被调用,这就导致了内存泄漏。