MST

星途 面试题库

面试题:C++数组传参指针操作与内存管理

编写一个C++程序,实现一个动态二维数组(通过`new`分配内存),并编写一个函数`void operateOnArray(int **arr, int rows, int cols)`,该函数接收动态二维数组的指针、行数和列数作为参数。在函数中,使用指针操作将数组所有元素置为其行列下标的乘积(即`arr[i][j] = i * j`)。完成操作后,在主函数中释放动态分配的内存。请阐述在这个过程中指针操作可能出现的内存泄漏问题及如何避免,同时分析C++ 智能指针是否适用于这种场景,如果适用,应如何使用。
47.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>

// 函数声明
void operateOnArray(int **arr, int rows, int cols);

int main() {
    int rows = 3;
    int cols = 4;

    // 动态分配二维数组内存
    int **arr = new int*[rows];
    for (int i = 0; i < rows; ++i) {
        arr[i] = new int[cols];
    }

    operateOnArray(arr, rows, cols);

    // 输出数组内容
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            std::cout << arr[i][j] << " ";
        }
        std::cout << std::endl;
    }

    // 释放内存
    for (int i = 0; i < rows; ++i) {
        delete[] arr[i];
    }
    delete[] arr;

    return 0;
}

void operateOnArray(int **arr, int rows, int cols) {
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            arr[i][j] = i * j;
        }
    }
}

内存泄漏问题及避免方法

  1. 内存泄漏问题
    • 如果在动态分配二维数组的过程中,内层new int[cols]成功,但外层new int*[rows]失败,由于已经分配了内层的内存,但没有对应的释放操作,会导致内存泄漏。
    • 如果在释放内存时,忘记释放内层数组(即只执行delete[] arr;而没有先delete[] arr[i];),也会导致内存泄漏。
  2. 避免方法
    • 在分配内存时,采用异常安全的方式。例如,使用智能指针(下面会分析)。如果不使用智能指针,在分配内层数组后,立即检查是否分配成功,如果失败,先释放之前分配的外层数组内存。
    • 在释放内存时,确保按照正确的顺序释放,先释放内层数组,再释放外层数组。

C++智能指针的适用性及使用方法

  1. 适用性:C++智能指针适用于这种场景,可以有效管理动态分配的内存,避免内存泄漏。
  2. 使用方法
    • 使用std::unique_ptr来管理二维数组。可以使用std::unique_ptr<int[]>来管理内层数组,std::unique_ptr<std::unique_ptr<int[]>[]>来管理外层数组。
#include <iostream>
#include <memory>

// 函数声明
void operateOnArray(std::unique_ptr<std::unique_ptr<int[]>[]> &arr, int rows, int cols);

int main() {
    int rows = 3;
    int cols = 4;

    // 动态分配二维数组内存
    std::unique_ptr<std::unique_ptr<int[]>[]> arr(new std::unique_ptr<int[]>[rows]);
    for (int i = 0; i < rows; ++i) {
        arr[i].reset(new int[cols]);
    }

    operateOnArray(arr, rows, cols);

    // 输出数组内容
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            std::cout << arr[i][j] << " ";
        }
        std::cout << std::endl;
    }

    // 智能指针会自动释放内存,无需手动释放

    return 0;
}

void operateOnArray(std::unique_ptr<std::unique_ptr<int[]>[]> &arr, int rows, int cols) {
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            arr[i][j] = i * j;
        }
    }
}

这样,使用智能指针可以简化内存管理,并且在对象生命周期结束时自动释放内存,有效避免内存泄漏。