MST

星途 面试题库

面试题:C++中delete与delete []在复杂内存布局场景下的应用

假设有一个复杂的数据结构,其中包含嵌套的动态数组,例如`int*** complexArr = new int**[3];`,每个`int**`又指向包含不同数量`int*`的数组,且每个`int*`指向不同大小的`int`数组。请详细描述如何正确使用`delete`和`delete []`来释放这一复杂数据结构的内存,同时分析在这个过程中如果错误使用`delete`和`delete []`可能引发的内存问题及其原理。
38.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 释放内存的正确方法

    • 对于最外层的动态数组int*** complexArr = new int**[3];,因为它是使用new []分配的,所以需要使用delete []来释放:
      for(int i = 0; i < 3; ++i) {
          int** innerArr = complexArr[i];
          if(innerArr != nullptr) {
              // 确定innerArr中int*数组的大小,假设可以通过某种方式获取到大小为sizeInner
              int sizeInner = getSizeOfInnerArray(innerArr);
              for(int j = 0; j < sizeInner; ++j) {
                  int* subInnerArr = innerArr[j];
                  if(subInnerArr != nullptr) {
                      // 确定subInnerArr中int数组的大小,假设可以通过某种方式获取到大小为sizeSubInner
                      int sizeSubInner = getSizeOfSubInnerArray(subInnerArr);
                      delete [] subInnerArr;
                  }
              }
              delete [] innerArr;
          }
      }
      delete [] complexArr;
      
    • 这里假设了两个函数getSizeOfInnerArraygetSizeOfSubInnerArray来获取内部数组的大小,实际应用中需要根据具体的数据结构设计来实现这两个函数。
  2. 错误使用deletedelete []可能引发的内存问题及其原理

    • 错误1:使用delete释放使用new []分配的数组
      • 问题:可能导致内存泄漏和未定义行为。
      • 原理new []分配内存时,除了分配对象所需的内存,还会额外记录数组的大小等信息(具体实现依赖于编译器)。delete []知道如何找到并正确释放这些额外信息以及数组中的所有对象。而delete只释放单个对象的内存,它不知道数组的大小,不会释放额外记录的数组大小信息,从而导致内存泄漏。同时,这是未定义行为,因为程序尝试以错误的方式释放内存,可能导致程序崩溃或其他不可预测的结果。
    • 错误2:使用delete []释放使用new分配的单个对象
      • 问题:同样会导致未定义行为。
      • 原理delete []期望释放的内存块是由new []分配的,它会按照数组的方式去释放内存,即尝试根据额外记录的数组大小信息来多次调用对象的析构函数(如果对象有析构函数)。但对于单个对象,内存布局并非数组形式,这就会导致程序访问越界等未定义行为,可能破坏内存中的其他数据,进而导致程序崩溃。