提问人:professional pro 提问时间:9/9/2022 更新时间:9/9/2022 访问量:322
sizeof() 如何与取消引用一起工作?
How does sizeof() work with a dereference?
问:
我最近看到的代码示例:
#include <stdio.h>
#include <stdlib.h>
struct x {
int a;
int b;
};
int main(void) {
struct x *ptr = malloc(sizeof(*ptr));
return 0;
}
甚至如何工作?
sizeof(*ptr)
如何取消引用未定义的指针,并赋予其正确的大小并生成正确的大小?(当然,它应该导致未定义的行为,因为它未定义)
sizeof()
最后,C 标准是否定义了这种行为?(也许在 C 中显示它是合法的,我找不到任何东西)
答:
sizeof
不是函数调用,而是运算符。它不适用于 的值,但不适用于其类型。 已声明为 类型,因此编译器知道它等价于 .ptr
ptr
struct x*
sizeof(*ptr)
sizeof(struct x)
演示。
运算符采用表达式或带括号的类型作为其参数。除非该参数是可变长度数组,否则它不会计算其参数。无论哪种方式,大小都是由操作数的类型确定的。sizeof
因此,给定一个指针,由于表达式的类型为 。这里没有评估,因此没有取消引用。或者,您可以使用 来查找 .在第一种情况下,操作数是表达式,在第二种情况下,操作数是带括号的类型。int *p
sizeof *p
int
*p
int
sizeof(int)
int
*p
(int)
可能值得评论,这是一个有用的 C 习语。不需要括号,因为这是一个表达式,而不是一个类型:struct x *ptr = malloc(sizeof(*ptr));
*ptr
*ptr
struct x *ptr = malloc(sizeof *ptr);
当类型发生变化时,这种结构是清晰且易于维护的,例如,当不再需要时,但现在需要时,只有一件事要改变:struct x
struct y
struct y *ptr = malloc(sizeof *ptr);
在此之后,一个简单的更改是指向 的指针,并且已为一个 分配了正确的内存量。ptr
struct y
struct y
ptr
实际上并没有在这里取消引用。运算符的操作数,在本例中为表达式 ,仅查看其类型。sizeof
*ptr
这在 C 标准第 6.5.3.4p2 节中关于运算符的详细说明:sizeof
运算符生成其操作数的大小(以字节为单位),其中 可以是表达式或带括号的类型名称。尺寸是 根据操作数的类型确定。结果是一个整数。如果 操作数的类型是可变长度数组类型,即操作数 被评估;否则,不会计算操作数和结果 是一个整数常量
sizeof
在这种特殊情况下,不计算,但看到它具有类型,因此计算为一个常量,其大小为 字节 。*ptr
struct x
sizeof(*ptr)
struct x
评论
siezof
不是一个函数,它是一个在编译时计算的运算符。编译器知道这是指向 的指针,因此将是一个 .编译器从结构定义中知道结构的大小。ptr
struct x
*ptr
struct x
malloc
ptr
struct x*
struct y*
malloc(sizeof(struct x))
sizeof(struct y)
sizeof(*ptr)
*ptr
struct y
malloc