我想使用指针动态分配2D数组。
int *arr = (int *)malloc(rows * cols * sizeof(int));
这可行,但是从技术上讲,这个单指针数组是2D数组吗?
谢谢!
答案 0 :(得分:1)
从技术上讲,它只是一维阵列。但是通过基于行优先顺序计算索引,它可以用作2D数组:
int index = row * cols + col;
int val = arr[index];
这是声明2D数组时发生的情况:
int arr[rows][cols]
int val = arr[row][col];
答案 1 :(得分:1)
以下是二维数组吗?
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
答案 2 :(得分:0)
int *arr = (int *)malloc(rows * cols * sizeof(int));
arr
是指向已分配rows * cols * sizeof(int)
个字节的存储位置的指针。
哪种语言解释存储位置无关紧要,取决于您。一维数组,二维数组,字符串等。在C语义中,它可能是一维数组,但这还不是全部,因为要由您来解释和管理内存的合适方式。
答案 3 :(得分:0)
否,指针从不是数组。请参阅comp.lang.c FAQ的第6节。
您可以使用此技术分配大块的内存,然后将其视为二维数组,指针arr
指向其初始元素。一种更简单,更好的书写方式是:
int *arr = malloc(rows * cols * sizeof (*arr));
这将分配rows*cols
int
个元素的一维数组。您不能使用arr[i][j]
表示法对其进行索引;您需要自己计算索引:arr[i * rows + j]
。
如果您想分配一个 dynamic 二维数组(或更准确地说,是一个像一个数组一样的数据结构),则需要创建一个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);
}