C++ 中,使用 new 声明二维数组可以通过三种方式:最常见的是创建指针数组,每个指针指向一行;性能更优的是分配一块连续内存并用指针数组映射每行;最简单的是用一维数组模拟二维索引,通过 row * cols + col 访问元素,三种方式各有取舍,需根据性能与可读性需求选择。

1、指针数组 + 每行单独分配

指针数组 + 每行单独分配是一种在 C++ 中使用 new 创建二维数组的常见方式,它通过先创建一个指针数组,每个指针再单独指向一个包含列元素的一维数组,结构清晰,访问直观,支持不规则二维结构(如每行列数不同),但由于内存非连续,释放时需要逐行 delete[],在高性能场景下可能不如连续分配方式高效。

#include<iostream>
using namespace std;

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

    // 创建一个 int* 数组,每个指针指向一行
    int** arr = new int*[rows];
    for (int i = 0; i < rows; ++i) {
        arr[i] = new int[cols];
    }

    // 填充值并打印
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            arr[i][j] = i * 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;
}

2、连续内存块 + 指针数组映射行

通过先分配一块连续的一维内存来存储所有二维数组元素,再创建一个指针数组将每一行映射到这块内存中对应的位置,既保持了访问上的二维数组语法,又提升了内存局部性和访问性能,非常适用于对性能要求较高的场景,如矩阵计算。

#include<iostream>
using namespace std;

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

    // 一块连续内存
    int* data = new int[rows * cols];

    // 每行的起始地址
    int** arr = new int*[rows];
    for (int i = 0; i < rows; ++i) {
        arr[i] = data + i * cols;
    }

    // 赋值并打印
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            arr[i][j] = i * cols + j;
            std::cout << arr[i][j] << " ";
        }
        std::cout << std::endl;
    }

    // 释放内存
    delete[] arr;
    delete[] data;

    return 0;
}

3、一维数组模拟二维数组

C++ 中,一维数组模拟二维数组是通过分配一块连续内存,并使用公式 arr[i * cols + j] 来访问二维坐标 (i, j) 对应的元素,这种方法内存布局紧凑、访问速度快,适合性能敏感的场景,但索引不直观、可读性略差。

#include<iostream>
using namespace std;

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

    // 分配一维数组
    int* arr = new int[rows * cols];

    // 填充并访问
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            arr[i * cols + j] = i * cols + j;
            std::cout << arr[i * cols + j] << " ";
        }
        std::cout << std::endl;
    }

    // 释放内存
    delete[] arr;

    return 0;
}

推荐文档