如何在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,提问作者Христо Тодоров
相关产品推荐
相关产品推荐

