【问题标题】:Confusion: Dynamic Allocation of 2D array, C困惑:二维数组的动态分配,C
【发布时间】:2012-12-02 16:27:01
【问题描述】:

我昨天在 SO 上遇到了一个 question,它想在 C 中动态分配一个二维数组。

答案之一是这样分配:

int (*place)[columns] = malloc(rows * sizeof *place);

这除了漂亮之外,还让我想到了一个问题。问题如下:

以下是我分配 4x4 的代码

    int (*arr)[4] = (int (*)[4]) malloc(4 * sizeof *arr);
    printf("%d\n", sizeof arr);                 //Dynamic 2-D array by above method
    
    int **arr1 = (int**) malloc(4 * sizeof(int*));
    for(int i = 0; i < 4; i++)
            arr1[i] = (int *) malloc(sizeof(double));
    printf("%d\n", sizeof arr1);                          //Usual dynamic 2-D array

    int *arr2 = (int*) malloc(4 * sizeof(int));
    printf("%d\n", sizeof arr2);                          //Dynamic 1-D array
    
    

通常的输出是:

4
4
4

但是,如果我尝试打印 sizeof *arrsizeof *arr1sizeof *arr2,则输出为:

16
4
4

我不明白为什么会这样。知道为什么sizeof *arr 的输出是16 吗?第一种情况下内存是如何分配的?

另外,当我尝试打印arr*arr 的地址时,两个打印的值都是相同的。 *arr 表示“价值”arr。那么这是否意味着 arr 存储自己的地址,即它指向自己(我认为这是不可能的)?我有点困惑。知道我哪里出错了吗?

感谢您的帮助!

【问题讨论】:

  • arr 和 *arr 的地址相同,因为数组中第一个元素的地址与第一行开头的地址相同。没有什么奇怪的。

标签: c arrays pointers sizeof


【解决方案1】:

但是,如果我尝试打印 sizeof *arrsizeof *arr1sizeof *arr2,我会得到 1644

地点:

int (*arr)[4];
int **arr1;
int *arr2;

您必须在 32 位机器上工作,而不是 64 位机器。

arr 的类型是“指向 4 个数组的指针 int”。当你取消引用它时,你会得到一个'array of 4 int'。当传递给 sizeof 时,数组的大小为 16 (4 * sizeof(int))。大多数情况下,当您引用一个数组时,类型会调整为“指向数组第零个元素的指针”,但sizeof() 是该规则的主要例外;它将数组视为数组并返回整个数组的大小。

arr1 的类型是“指向int 的指针”。当你取消引用它时,你会得到一个'指向int'的指针。当传递给 sizeof 时,指针大小为 4 (sizeof(int *))。

arr2 的类型是“指向int 的指针”。当你取消引用它时,你会得到一个int。当传递给sizeof 时,int 的大小为 4。


好的!我得到了大部分。但是......为什么当我做sizeof arr2时输出不是16?

正如詹姆斯在评论中指出的那样:

因为sizeof(arr2) 减少到sizeof(int*),在 32 位机器上是 4。

arr2是一个指针;在 32 位机器上指针的大小是 4。

此外,arr 是“指向 4 个 int 数组的指针”,即单个指针。那我怎么得到一个 4×4 的矩阵呢。

您可以使用以下任何一种:

int mat1[4][4];
int (*mat2)[4][4];

第一个是直接的 4×4 矩阵。 sizeof(mat1) 的结果在 32 位机器上将是 64(和大多数 64 位机器一样)。

第二个是指向int 的4×4 矩阵的指针。 sizeof(mat2) 的结果在 32 位机器上将为 4; mat2 是一个指针(指向 int 的 4×4 矩阵),因此它的大小为 4,与所有其他对象指针相同(实际上,与每个函数指针的大小相同,尽管 C标准不保证函数指针和对象指针的大小相同;但 POSIX 确实保证)。

sizeof(*mat2)的结果是mat2指向的对象的大小,是int的4×4矩阵,所以大小又是64。

【讨论】:

  • 好的!我得到了大部分。但是你说:“大多数时候,当你引用一个数组时,类型会调整为'指向数组第零元素的指针',但 sizeof() 是该规则的主要例外”。那为什么当我执行sizeof arr2 时输出不是16
  • @shrey347 因为 sizeof(arr2) 减少到 sizeof(int*) 在 32 位机器上是 4
  • 另外,arr 是一个“指向 4 个 int 的数组的指针”,即单个指针。那么我如何得到一个 4x4 矩阵。对不起,如果这看起来很愚蠢!
  • @shrey347: arr 是一个指向 4x4 数组的第一个元素的指针。但是,给定一个指向数组第一个元素的指针,您不知道(也无法找出)数组有多大。
【解决方案2】:

在 32 位系统中,它需要 4 个字节或 32 位来唯一标识每个内存地址。指针只是地址的持有者。所以它需要4个字节。在第一种情况下,arr 是一个长度为 4 的指针数组。所以它需要 4*4 =16 个字节。在其他两种情况下, arr1 和 arr2 只是一个指针。所以它们占用 4 个字节。

【讨论】:

    猜你喜欢
    • 2021-02-03
    • 2015-02-10
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    • 2015-06-10
    • 2014-07-19
    • 1970-01-01
    相关资源
    最近更新 更多