MST

星途 面试题库

面试题:C++ 中析构函数调用时机与作用相关基础问题

请描述在一个包含动态内存分配的类中,析构函数通常在哪些情况下会被调用?并举例说明析构函数如何释放动态分配的内存以避免内存泄漏。
37.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

析构函数调用情况

  1. 对象生命周期结束:当对象在其作用域结束时,析构函数会被自动调用。例如在函数内部定义的局部对象,当函数执行完毕,该局部对象的生命周期结束,析构函数被调用。
void someFunction() {
    class MyClass {
    public:
        MyClass() { data = new int[10]; }
        ~MyClass() { delete[] data; }
    private:
        int* data;
    };
    MyClass obj;
    // 当函数执行到这里,obj生命周期结束,析构函数被调用
}
  1. 对象被显式删除:如果使用new动态分配了对象,当使用delete来释放该对象时,析构函数会被调用。
class MyClass {
public:
    MyClass() { data = new int[10]; }
    ~MyClass() { delete[] data; }
private:
    int* data;
};
int main() {
    MyClass* obj = new MyClass();
    delete obj;
    // 这里delete调用后,MyClass的析构函数被调用
    return 0;
}
  1. 包含对象的容器被销毁:当一个包含对象的容器(如std::vectorstd::list等)被销毁时,容器中每个对象的析构函数都会被调用。
#include <vector>
class MyClass {
public:
    MyClass() { data = new int[10]; }
    ~MyClass() { delete[] data; }
private:
    int* data;
};
int main() {
    std::vector<MyClass> vec;
    vec.push_back(MyClass());
    // 当vec生命周期结束(例如函数结束),vec中每个MyClass对象的析构函数被调用
    return 0;
}

释放动态分配内存避免内存泄漏示例

class MyClass {
public:
    MyClass() {
        // 动态分配内存
        data = new int[10]; 
    }
    ~MyClass() {
        // 释放动态分配的内存
        delete[] data; 
    }
private:
    int* data;
};

在上述MyClass类中,构造函数使用new int[10]分配了一块内存。析构函数中使用delete[] data来释放这块内存。如果没有析构函数或者析构函数中没有正确释放内存,那么当对象销毁时,这块动态分配的内存就无法被回收,从而导致内存泄漏。