You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中声明二维动态数组?行动态列固定的二维数组怎么声明?

嘿,针对你提出的两个C++数组问题,我给你整理了不用STL容器的原生实现方案,都是工程里常用的写法:

一、声明二维动态数组(行列均为动态)

这里有两种主流实现方式,各有优劣,你可以按需选择:

方式1:指针的指针(非连续内存)

这种方式先分配一个存储行指针的数组,再给每个行单独分配列内存,好处是可以灵活设置每行的长度(如果需要的话),缺点是内存不连续,缓存友好性稍差。

代码示例(malloc/free版本):

#include <iostream>
#include <cstdlib>

int main() {
    int rows = 5; // 动态行数量
    int cols = 4; // 动态列数量

    // 分配行指针数组
    int** arr = (int**)malloc(rows * sizeof(int*));
    if (!arr) { /* 内存分配失败处理 */ }

    // 给每行分配列内存并初始化
    for (int i = 0; i < rows; ++i) {
        arr[i] = (int*)malloc(cols * sizeof(int));
        if (!arr[i]) { /* 内存分配失败处理 */ }
        for (int j = 0; j < cols; ++j) {
            arr[i][j] = i * cols + j;
        }
    }

    // 使用数组
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            std::cout << arr[i][j] << " ";
        }
        std::cout << "\n";
    }

    // 必须先释放每行,再释放行指针数组,避免内存泄漏
    for (int i = 0; i < rows; ++i) {
        free(arr[i]);
    }
    free(arr);

    return 0;
}

如果习惯用C++的new/delete,写法类似:

int** arr = new int*[rows];
for (int i = 0; i < rows; ++i) {
    arr[i] = new int[cols];
}

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

方式2:一维数组模拟二维(连续内存)

把二维数组当成一块连续的一维内存,通过索引计算来访问元素,好处是内存连续,缓存友好,释放内存也更简单(只需要一次释放)。

代码示例:

#include <iostream>
#include <cstdlib>

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

    // 分配连续内存
    int* arr_flat = (int*)malloc(rows * cols * sizeof(int));
    if (!arr_flat) { /* 内存分配失败处理 */ }

    // 访问arr[i][j]等价于arr_flat[i * cols + j]
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            arr_flat[i * cols + j] = i * cols + j;
            std::cout << arr_flat[i * cols + j] << " ";
        }
        std::cout << "\n";
    }

    // 一次释放即可
    free(arr_flat);

    return 0;
}
二、行动态但列长度固定的二维数组(无需行列均动态)

当然存在这种实现方式!而且这种场景下,我们可以利用C++的数组指针特性,实现既支持动态行数,又能直接用[][]访问的数组,同时内存还是连续的。

核心思路是:声明一个指向固定大小数组的指针,然后动态分配对应行数的内存块。

代码示例(列数固定为3):

#include <iostream>
#include <cstdlib>

const int FIXED_COLS = 3; // 编译期固定的列数

int main() {
    int rows = 5; // 动态指定行数

    // 分配内存:指向固定大小数组的指针
    int (*arr)[FIXED_COLS] = (int (*)[FIXED_COLS])malloc(rows * FIXED_COLS * sizeof(int));
    if (!arr) { /* 内存分配失败处理 */ }

    // 直接用[][]访问,编译器知道列数,会自动计算偏移
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < FIXED_COLS; ++j) {
            arr[i][j] = i * FIXED_COLS + j;
            std::cout << arr[i][j] << " ";
        }
        std::cout << "\n";
    }

    // 一次释放所有内存
    free(arr);

    // 用new/delete的写法更简洁
    int (*arr_new)[FIXED_COLS] = new int[rows][FIXED_COLS];
    delete[] arr_new;

    return 0;
}

补充说明

如果你的列数是运行时才能确定(而非编译期固定),GCC等编译器支持变长数组(VLA)扩展,比如int arr[rows][fixed_cols],但这不是标准C特性,跨平台兼容性差,不推荐使用。所以优先用上面的数组指针方案,完全符合标准C,且满足你的需求。

内容的提问来源于stack exchange,提问作者Христо Тодоров

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 12:02:41