MST

星途 面试题库

面试题:C++指针内存管理与异常处理

假设有一个包含指针成员变量的类,在实现其拷贝构造函数、赋值运算符重载和析构函数时,如何确保正确的内存管理?如果在这些函数中可能抛出异常,又该如何处理以避免内存泄漏和悬空指针等问题?请编写代码示例。
31.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. 确保正确内存管理的方法

  • 拷贝构造函数:深拷贝指针成员变量,即分配新的内存并复制数据。
  • 赋值运算符重载:释放旧的内存(如果有),然后进行深拷贝。
  • 析构函数:释放指针成员变量所指向的内存。

2. 处理异常的方法

  • 使用智能指针(如 std::unique_ptrstd::shared_ptr)来管理动态内存,它们会自动处理内存释放,即使抛出异常也能保证内存安全。

代码示例

#include <iostream>
#include <memory>

class MyClass {
private:
    std::unique_ptr<int[]> data;
    int size;

public:
    // 构造函数
    MyClass(int s) : size(s) {
        data = std::make_unique<int[]>(size);
        for (int i = 0; i < size; ++i) {
            data[i] = i;
        }
    }

    // 拷贝构造函数
    MyClass(const MyClass& other) : size(other.size) {
        data = std::make_unique<int[]>(size);
        for (int i = 0; i < size; ++i) {
            data[i] = other.data[i];
        }
    }

    // 赋值运算符重载
    MyClass& operator=(const MyClass& other) {
        if (this != &other) {
            size = other.size;
            data = std::make_unique<int[]>(size);
            for (int i = 0; i < size; ++i) {
                data[i] = other.data[i];
            }
        }
        return *this;
    }

    // 析构函数
    ~MyClass() = default;

    // 打印数据的函数
    void printData() const {
        for (int i = 0; i < size; ++i) {
            std::cout << data[i] << " ";
        }
        std::cout << std::endl;
    }
};

int main() {
    MyClass a(5);
    MyClass b(a);
    MyClass c(3);
    c = a;

    a.printData();
    b.printData();
    c.printData();

    return 0;
}

在上述代码中:

  • 使用 std::unique_ptr<int[]> 来管理动态分配的数组 data,从而自动处理内存释放。
  • 拷贝构造函数和赋值运算符重载进行了深拷贝操作,确保每个对象都有自己独立的内存。
  • 析构函数使用默认实现,因为 std::unique_ptr 会自动处理内存释放。这样在可能抛出异常的情况下,也能避免内存泄漏和悬空指针问题。