MST

星途 面试题库

面试题:C++编译器自动生成缺省函数与内存管理

假设我们有一个类,其中包含指向动态分配内存的指针成员。当编译器自动生成四个缺省函数(默认构造函数、拷贝构造函数、赋值运算符重载、析构函数)时,分析在不同场景下(对象创建、拷贝、赋值、销毁)可能出现的内存管理问题,并说明如何通过手动实现这些函数来解决这些问题。
29.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. 可能出现的内存管理问题

  • 对象创建(默认构造函数)
    • 问题:若默认构造函数没有初始化指针成员指向的动态内存,使用该对象时可能导致未定义行为,因为指针处于未初始化状态。
  • 对象拷贝(拷贝构造函数)
    • 问题:编译器自动生成的拷贝构造函数执行浅拷贝,即仅仅复制指针的值,而非动态分配的内存内容。这意味着多个对象将指向同一块内存,当其中一个对象销毁这块内存时,其他对象的指针就成为野指针,再次访问会导致未定义行为。
  • 对象赋值(赋值运算符重载)
    • 问题:自动生成的赋值运算符重载同样执行浅拷贝,和拷贝构造函数类似,会造成多个对象指向同一块动态内存,并且在释放内存时会产生重复释放的问题,导致程序崩溃。
  • 对象销毁(析构函数)
    • 问题:自动生成的析构函数不会释放指针成员指向的动态内存,从而导致内存泄漏,因为动态分配的内存没有被释放。

2. 手动实现这些函数来解决问题

  • 默认构造函数
class MyClass {
private:
    int* data;
public:
    MyClass() {
        data = new int;
        *data = 0; // 初始化数据
    }
};
  • 拷贝构造函数
class MyClass {
private:
    int* data;
public:
    MyClass(const MyClass& other) {
        data = new int;
        *data = *other.data; // 深拷贝,分配新内存并复制内容
    }
};
  • 赋值运算符重载
class MyClass {
private:
    int* data;
public:
    MyClass& operator=(const MyClass& other) {
        if (this != &other) {
            delete data;
            data = new int;
            *data = *other.data; // 释放原有内存,分配新内存并复制内容
        }
        return *this;
    }
};
  • 析构函数
class MyClass {
private:
    int* data;
public:
    ~MyClass() {
        delete data; // 释放动态分配的内存
    }
};

通过手动实现上述四个函数,分别在对象创建时正确初始化动态内存,拷贝和赋值时执行深拷贝,销毁时释放动态内存,从而解决自动生成的缺省函数带来的内存管理问题。