我想使用指针动态分配 2D 数组。
int *arr = (int *)malloc(rows * cols * sizeof(int));
这有效,但这个单指针数组在技术上是 2D 数组吗?
谢谢!
从技术上讲,它只是一个 1D 数组。但它可以通过基于行主要排序计算索引来用作 2D 数组:
int index = row * cols + col;
int val = arr[index];
这就是声明 2D 数组时幕后发生的事情:
int arr[rows][cols]
int val = arr[row][col];
以下是 2D 数组吗?
int *arr = (int *)malloc(rows * cols * sizeof(int));
不。arr
是一个指针。 该指针使用适合存储 2D 数组的内存地址进行初始化。
我想使用指针动态分配 2D 数组。
这取决于"2D"的类型
"2D 阵列"的概念经常被松散地使用。 让我们探讨一些可能的解释。
若要分配指向 2D 数组的指针,请使用以下命令。如果rows,cols
是常量或代码为 C99,或具有可变长度数组的 C11:
int (*arr_true)[rows][cols] = malloc(sizeof *arr_true);
(*arr_true)[0][0] = this;
(*arr_true)[0][1] = that;
// etc.
为宽度cols
2D 数组分配内存。 如果cols
是常量或代码是 C99,或者具有可变长度数组的 C11:
int *arr_mem[cols] = malloc(sizeof *arr_mem * rows);
arr_mem[0][0] = this;
arr_mem[0][1] = that;
// etc.
为包含row*cols
元素的数组分配内存。
int *arr_flat = malloc(sizeof *arr_flat *rows * cols);
arr_flat[0 *cols + 0] = this;
arr_flat[0 *cols + 1] = that;
// etc.
将指针数组分配给int
指针
int *arr_classic = malloc(sizeof *arr_classic *rows);
for (size_t r = 0; r<rows; r++) {
arr_classic[r] = malloc(sizeof *arr_classic[r] *cols);
}
arr_classic[0][0] = this;
arr_classic[0][1] = this;
// etc.
尺寸计算的改进思路。
考虑用于计算大小的数学。 如果rows,cols
int
,rows * cols
可能会溢出int
范围,导致未定义的行为。 使用size_t
完成的相同计算可能不会在数学上溢出,应首选。
最后,malloc(size_t sz)
期待一个size_t
,
int *arrA = malloc(rows * cols * sizeof(int)); // possible int*int overflow
int *arrB = malloc(sizeof(int) * rows * cols); // preferred
int *arr = (int *)malloc(rows * cols * sizeof(int));
arr
是指向具有rows * cols * sizeof(int)
分配字节的内存位置的指针。
对于语言来说,您将内存位置解释为什么并不重要,这取决于您。 一维数组、二维数组、字符串等在C语义中,它可能是一个1D数组,但这仍然不是全部事实,因为由您来解释和管理您认为合适的内存。
不,指针从来都不是数组。请参阅 comp.lang.c FAQ 的第 6 节。
您可以使用此技术分配内存块,然后可以将其视为二维数组,指针arr
指向其初始元素。 一种更简单更好的编写方法是:
int *arr = malloc(rows * cols * sizeof (*arr));
这将分配一个rows*cols
int
元素的一维数组。不能使用arr[i][j]
表示法为其编制索引;您需要自己计算索引:arr[i * rows + j]
.
如果要分配一个动态二维数组(或者更准确地说,是一个类似于一个的数据结构(,则需要创建一个int**
指针数组,并初始化每个元素以指向新分配的int
元素数组。(然后你需要清理它,你完成了它。 例如:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int cols = 20;
int rows = 10;
// Allocate memory for an array of pointers to rows
int **arr_2d = malloc(rows * sizeof *arr_2d);
if (arr_2d == NULL) {
abort(); // horribly crude error handling
}
// Allocate memory for each row
for (int row = 0; row < rows; row ++) {
int *arr_1d = malloc(cols * sizeof *arr_1d);
if (arr_1d == NULL) {
abort(); // horribly crude error handling
}
arr_2d[row] = arr_1d;
}
// Assign data
for (int row = 0; row < rows; row ++) {
for (int col = 0; col < cols; col ++) {
arr_2d[row][col] = row*col;
}
}
// Dump data
for (int row = 0; row < rows; row ++) {
printf("Row %2d:", row);
for (int col = 0; col < cols; col ++) {
printf(" %3d", arr_2d[row][col]);
}
putchar('n');
}
// Deallocate each row
for (int row = 0; row < rows; row ++) {
free(arr_2d[row]);
}
// Deallocate the array of row pointers
free(arr_2d);
}