困惑:2D阵列的动态分配,C

时间:2012-12-02 16:27:02

标签: c arrays pointers sizeof

我昨天在SO上遇到question,希望在C中动态分配2-D数组。

其中一个答案是以这种方式分配:

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存储了自己的地址,即它指向自身(我认为不可能)?我有点困惑。知道我哪里错了吗?

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

  

但是,如果我尝试打印sizeof *arrsizeof *arr1sizeof *arr2,我会1644。< / p>

其中:

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

您必须使用的是32位计算机,而不是64位计算机。

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

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

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


  

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

詹姆斯在评论中指出:

  

因为sizeof(arr2)缩减为sizeof(int*),而32位计算机上的arr2为4。

也就是说,int mat1[4][4]; int (*mat2)[4][4]; 是一个指针;在32位计算机上,指针的大小为4。

  

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

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

sizeof(mat1)

第一个是直接的4×4矩阵。 int的结果在32位计算机上将是64(并且大多数64位计算机都会发生)。

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

mat2的结果是int指向的对象的大小,它是{{1}}的4×4矩阵,因此大小再次为64。

答案 1 :(得分:1)

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