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; }