0

我昨天遇到了一个关于 SO 的问题,它想在 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 *arr,sizeof *arr1sizeof *arr2,则输出为:

16
4
4

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

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

谢谢你的帮助!

4

2 回答 2

3

但是,如果我尝试打印sizeof *arr,sizeof *arr1sizeof *arr2,我会得到16,44.

在哪里:

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. 当传递给 时sizeofint大小为 4。


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

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

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

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

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

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

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

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

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

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

于 2012-12-02T16:34:09.587 回答
1

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

于 2012-12-02T16:34:46.753 回答