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