为啥在 C 中为数组声明和指向数组声明的指针动态分配的内存不同? [复制]

Posted

技术标签:

【中文标题】为啥在 C 中为数组声明和指向数组声明的指针动态分配的内存不同? [复制]【英文标题】:Why isn't the dynamically allocated memory for an array declaration and a pointer to an array declaration the same in C? [duplicate]为什么在 C 中为数组声明和指向数组声明的指针动态分配的内存不同? [复制] 【发布时间】:2021-11-15 20:11:41 【问题描述】:

考虑以下 C 代码 sn-p:

int main() 
  int *crr;
  int arr[] = 1, 2, 3, 45;
  crr = (int *)malloc(sizeof arr);
  printf("%ld\n", sizeof arr);
  printf("%ld", sizeof crr);
  return 0;

以上代码的输出是:

16
8

我有 64 位架构系统。因此,int 是 4 个字节。需要解释或任何参考来说明为什么会发生这种情况。我为crr 分配了相同数量的内存。

【问题讨论】:

sizeof array != sizeof pointer。您可能会喜欢comp.lang.c faq 的第 6 部分。 @pmg 所以我可以安全地做crr[3] = 4 是的,在这种情况下。因为sizeof arr 足够大(它是 * == )。 crr指向一个16字节的内存块,足够4个整数的空间; arr 是一个内存块,有足够的空间容纳 4 个整数。 正确! crr 是一个指针; sizeof crr 给出指针的大小。 crr[3] = 4 仅在您验证 crr != NULL 后才是正确的 【参考方案1】:

sizeof arr 计算为arr 的大小(以字节为单位)。因为arr是四个四字节int的数组,所以它的大小是16字节。

sizeof crr 的大小等于crr。因为crr是一个八字节的指针,所以它的大小是八字节。

您可能已经习惯了数组通常会自动转换为指针的事实。将数组传递给函数时,会将其转换为指针。在索引表达式中使用数组时,例如arr[2],将其转换为指针(然后通过指针运算将索引添加到其中,并将生成的指针取消引用,就好像它已经写了@987654329 @)。 sizeof 不会发生这种自动转换。 C 2018 6.3.2.1 3 说:

除非它是 sizeof 运算符的操作数,或一元 & 运算符,或者是用于初始化数组的字符串字面量,否则表达式类型为“array of type” >”被转换为类型为“pointer to type”的表达式,它指向数组对象的初始元素,而不是左值……

【讨论】:

以上是关于为啥在 C 中为数组声明和指向数组声明的指针动态分配的内存不同? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

指向动态声明的 cstrings 数组的指针

C语言如何声明一个返回函数指针的函数?

在 C 中声明指向结构的指针数组,但在需要之前不为结构分配内存

在C中为结构指针数组成员分配地址

为啥派生类对象的指针数组无法声明

动态内存分配与指向它的指针变量