这是以下代码的输出
int m[4]
sizeof(m) is 16 byte
sizeof(&m) is 8 byte
sizeof(*m) is 4 byte
int *p = malloc(sizeof(int)*4)
sizeof(p) is 8 byte
sizeof(&p) is 8 byte
sizeof(*p) is 4 byte
从每个示例中,我只能清楚 3 行。它们意味着我们取消引用指针并转到地址 - 并且有一些 int 类型,其大小为 4 个字节。
怎么变成16字节似乎也找到了答案——当sizeof包含数组指针时,它指向整个数组。所以 4*4 = 16 个字节。为什么其他都是 8 字节?以及如果我使用 malloc,我如何在 sizeof 中这样写 - 以获得分配的字节数 - 即 如何类比写sizeof(m)得到16。
int m[4];
printf("int m[4]\n");
printf(" sizeof(m) is %lu byte\n", sizeof(m));
printf(" sizeof(&m) is %lu byte\n", sizeof(&m));
printf(" sizeof(*m) is %lu byte\n\n", sizeof(*m));// здесь я понял - разименовываем, идем по адресу а там число int у которого размер 4 байта
int *p = malloc(sizeof(int)*4);
printf("int *p = malloc(sizeof(int)*4)\n");
printf(" sizeof(p) is %lu byte\n", sizeof(p));
printf(" sizeof(&p) is %lu byte\n", sizeof(&p));
printf(" sizeof(*p) is %lu byte\n", sizeof(*p));
C语言中没有“数组指针”的概念,所以这个解释是不正确的。
该运算符
sizeof返回指定为操作数的表达式类型的大小。同时比较特殊的sizeof是,如果指定为操作数的表达式是“数组”类型,则不会进行传统的自动转换为“指针”类型。(运算符sizeof是四种特殊 C 语言上下文之一的示例,其中数组类型不转换为指针类型。)因此在你的
操作数是
(m)类型的表达式int[4]。没有将数组转换为m“指针”类型(并且它周围的额外括号m不会影响这一点),也就是说,给定的sizeof将返回 type 的大小int[4],正如您自己正确指出的那样,它是 16 .此过程中不涉及“数组指针”。
您的
因为操作数有表达式
(&m),(p)和(&p)。所有这些表达式都是“指针”类型的。在第一种情况下,它是类型的指针int (*)[4],在第二种情况下int *,在第三种情况下int **。因此,这些sizeof将返回相应指针类型的大小。你平台上的所有结果都等于 8。理论上,这些异构指针可以有不同的大小,但实际上它们通常是相同的。它们的大小由平台参数决定,包括。选定的内存模型。
没门。C语言中没有这种可能性(
sizeof也绝对没有关系)。无法通过标准方法获得分配的内存块的实际大小。记住你分配了多少内存是你的工作。运算符
sizeof提供给定操作数的大小(以字节为单位)。来自 C 标准(6.5.3.4 The sizeof and alignof operators)
在这段代码中
声明一个包含四个类型元素的数组
int。内存中的数组存储为单个连续块。因此,这个表达式与运算符sizeof的值为
4 * sizeof( int ),如果类型对象int的大小为 4,则前面的表达式将返回值 16。当在 中使用数组名称时
sizeof,它不会转换为指向其第一个元素的指针。在这个表达式中
该语句
sizeof使用了一个指针&m,因此返回该指针占用的内存字节数的值。在您的平台上,此值为 8 个字节。在这个表达式中
sizeof类型的对象用作operator 的操作数int,因为将 * 运算符应用于数组名称首先将数组名称隐式转换为指向其第一个数组元素的指针,然后取消引用该指针。结果,将获得数组的第一个元素,它是 int 类型的。在这段代码中
p声明了类型指针int *。从前面的代码片段的分析中我们已经知道,指针的大小等于 8 个字节。因此,下面的表达式带有运算符sizeof在您的平台上将返回 8 的值。
在这个表达式中
还使用了一个指针,它指向一个变量
p,而变量又是一个指针。也就是说,表达式&p的类型为int **。因此,表达式的值为 8。在这个表达式中
指针被取消引用。结果,表达式
*p的类型int为 ,表达式的值为数字 4。指针不存储信息,无论它们是寻址单个对象还是某个数组的第一个对象。
例如,在这段代码中
指针
p首先被初始化为数组第一个元素的地址a,然后它的值被更改为单个对象的地址x。因此,如果你动态分配内存,那么你必须自己控制分配内存的大小。分配的内存可能比要求的多,或者相反,错误地分配的比要求的少。
该函数
malloc仅返回所选部分开头地址的值。所以你可以,例如,写
或者
或者
并将指针视为指向单个类型的对象
int。除了程序员自己,没有人也没有任何东西会监控分配的内存是如何使用的,是否被正确使用。返回到您的第二个代码片段,您可以声明一个指针,而不是指向 type 的对象,
int而是指向 type 的四个元素的数组int。例如,然后在取消引用的指针上使用 sizeof 运算符,您可以获得数组的大小
等于 16 个字节。也就是说,在这种情况下,指针指向的对象不是 类型的对象
int,而是 类型的对象int[4]。但是,要访问此数组的元素,您必须编写,例如,或者
i一些索引在哪里。您很可能使用 64 位编译器 - 这是指针大小,等于 8 个字节。
sizeof使用指针是不可能得到分配内存区域的大小的。单独存放。(如果他们告诉你内存管理器以某种方式记住了分配块的大小,那么是的。它确实如此。但这取决于具体的实现、编译器、操作系统等。此外,它很可能是更多的内存已分配比请求...)