C/C++二维数组创建内存分配
文章目录
- 一、传统“指针的指针”写法(行不连续)
- C写法
- cpp写法
- 二、一次性分配连续内存(推荐)
- c写法
- cpp写法
- 三、极简“扁平化”写法(无二级指针)
一、传统“指针的指针”写法(行不连续)
适用场景:行列都在运行期确定,且每行长度可不同(锯齿数组)。
C写法
#include <stdio.h>
#include <stdlib.h>int main(void) {int rows = 3, cols = 4;/* 1. 先给行指针数组分配空间 */int **arr = (int **)malloc(rows * sizeof(int *));if (!arr) { perror("malloc rows"); return 1; }/* 2. 再给每一行分配列空间 */for (int i = 0; i < rows; ++i) {arr[i] = (int *)malloc(cols * sizeof(int));if (!arr[i]) { perror("malloc cols"); return 1; }}/* 3. 使用:arr[i][j] = ... */for (int i = 0; i < rows; ++i)for (int j = 0; j < cols; ++j)arr[i][j] = i * cols + j;/* 4. 打印验证 */for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; ++j)printf("%2d ", arr[i][j]);putchar('\n');}/* 5. 释放:先逐行,再释放行指针 */for (int i = 0; i < rows; ++i)free(arr[i]);free(arr);return 0;
}
cpp写法
int rows = 3, cols = 4;// 1. 先分配行指针数组
int** arr = new int*[rows];// 2. 再给每一行分配列空间
for (int i = 0; i < rows; ++i)arr[i] = new int[cols];// 3. 使用,赋值
for (int i = 0; i < rows; ++i)for (int j = 0; j < cols; ++j)arr[i][j] = i * cols + j;/* 4. 打印验证 */
for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; ++j)printf("%2d ", arr[i][j]);putchar('\n');
}
// 4. 释放:先逐行,再释放行指针
for (int i = 0; i < rows; ++i)delete[] arr[i];
delete[] arr;
#include <vector>
#include <iostream>int main() {// 3 行 4 列,全部初始化为 0int rows = 3;int cols = 4;std::vector<std::vector<int>> arr(rows, std::vector<int>(cols, 0));// 使用,赋值for (int i = 0; i < rows; ++i)for (int j = 0; j < cols; ++j)arr[i][j] = i * cols + j;/* 4. 打印验证 */for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; ++j)printf("%2d ", arr[i][j]);putchar('\n');}
}
内存示意图:
缺点:
行与行之间内存不连续,缓存命中率低。
需要多个 new,释放顺序易出错。
二、一次性分配连续内存(推荐)
适用场景:行列已知,需要整块连续内存,效率高,易与 C API 交互。
c写法
#include <stdio.h>
#include <stdlib.h>int main(void) {int rows = 3, cols = 4;/* 1. 一次性申请所有元素 + 行指针数组 */int **arr = (int **)malloc(rows * sizeof(int *));int *data = (int *)malloc(rows * cols * sizeof(int));/* 2. 让行指针指向连续块的正确偏移 */for (int i = 0; i < rows; ++i)arr[i] = data + i * cols; // 关键一步/* 3. 使用与赋值 */for (int i = 0; i < rows; ++i)for (int j = 0; j < cols; ++j)arr[i][j] = i * cols + j;/* 4. 打印 */for (int i = 0; i < rows; ++i) {for (int j = 0; j < cols; ++j)printf("%2d ", arr[i][j]);putchar('\n');}/* 5. 释放:只需两步,顺序随意 */free(data);free(arr);return 0;
}
cpp写法
int rows = 3, cols = 4;// 1. 一次性申请全部元素
int* data = new int[rows * cols];// 2. 用下标或辅助宏访问
auto at = [&](int r, int c) -> int& { return data[r * cols + c]; };
for (int i = 0; i < rows; ++i)for (int j = 0; j < cols; ++j)at(i, j) = i * cols + j;// 3. 释放
delete[] data;
内存示意图:
data -> [0][1][2][3][4][5][6][7][8][9][10][11] // 连续
优点:
只有一段内存,缓存友好,易 delete[] data 一步释放。
三、极简“扁平化”写法(无二级指针)
如果你不需要 arr[i][j] 语法,可直接用一维指针模拟二维访问:
int rows = 3, cols = 4;
int *a = (int *)malloc(rows * cols * sizeof(int));
a[i * cols + j] = value; // 访问元素free(a);