以下是二维数组吗?

时间:2018-09-27 20:47:22

标签: c arrays pointers malloc

我想使用指针动态分配2D数组。

int *arr = (int *)malloc(rows * cols * sizeof(int));

这可行,但是从技术上讲,这个单指针数组是2D数组吗?

谢谢!

4 个答案:

答案 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,colsint,则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);
}