[英]Confusion: Dynamic Allocation of 2D array, C
昨天我遇到了一个关于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 *arr1
和sizeof *arr2
,则输出为:
16
4
4
我不明白为什么会这样。 知道为什么sizeof *arr
的输出为16
吗? 在第一种情况下如何分配内存?
另外,当我尝试打印arr
和*arr
的地址时,两个打印的值都相同。 *arr
意指“值” arr
。 那么这是否意味着arr存储了自己的地址,即它指向自己(我认为这是不可能的)? 我有点困惑。 知道我哪里出错了吗?
谢谢你的帮助!
但是,如果我尝试打印
sizeof *arr
,sizeof *arr1
和sizeof *arr2
,我得到16
,4
,和4
。
哪里:
int (*arr)[4];
int **arr1;
int *arr2;
您必须在32位计算机上工作,而不是在64位计算机上工作。
arr
的类型是“指向4个int
数组的指针”。 取消引用时,将得到一个“ 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。
在32位系统中,它需要4个字节或32位来唯一地标识每个内存地址。 指针不仅仅是地址的持有者。 因此需要4个字节。 在第一种情况下,arr是长度为4的指针数组。因此,它需要4 * 4 = 16字节。 在另外两种情况下,arr1和arr2只是一个指针。 因此它们占用4个字节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.