在此代码中,为什么sizeof(x)
是指针的大小,而不是x
类型的大小?
typedef struct {
...
} x;
void foo() {
x *x = malloc(sizeof(x));
}
答案 0 :(得分:6)
因为C说:
(C99,6.2.1p7)“任何其他标识符的范围都在其声明者完成之后开始。”
因此,在您的示例中,对象x
的范围始于x *x
之后:
x *x = /* scope of object x starts here */
malloc(sizeof(x));
为了说服自己,在声明对象x
之后立即放置另一个类型为x
的对象声明:您将收到编译错误:
void foo(void)
{
x *x = malloc(sizeof(x)); // OK
x *a; // Error, x is now the name of an object
}
否则,正如Shahbaz在另一个答案的评论中所说,这仍然不能正确使用malloc
。你应该这样叫malloc
:
T *a = malloc(sizeof *a);
而不是
T *a = malloc(sizeof a);
答案 1 :(得分:5)
这是因为sizeof(x)
使用x
的最内层定义,它是指针。要避免此问题,请不要对类型和变量使用相同的名称。
答案 2 :(得分:0)
不提供不同的名称(不仅仅是编程),这是一个坏主意:
行为观察者的学术原因已经被我的亲爱的注释者提到了。
明确建议名称diffenet thing differentnet(这里:变量类型和变量实例):
typedef struct {
...
} X;
void foo() {
X *x = malloc(sizeof(X));
}
对这个例子进行编码的更灵活的方法是(Shahbaz的评论也已经提到过):
typedef struct {
...
} X;
void foo() {
X *x = malloc(sizeof(*x));
}
后一个示例允许您更改x
的类型,而无需更改执行分配的代码。
这种方法的缺点是你可以在不通过编译器通知的情况下从使用引用转换为数组和版本vica(作为x
的类型),并破坏你的代码。