在这段代码中,为什么是sizeof(x)
指针的大小,而不是类型的大小x
?
typedef struct {
...
} x;
void foo() {
x *x = malloc(sizeof(x));
}
因为 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);
这是因为sizeof(x)
使用了 的最内层定义x
,即指针。为避免此问题,请不要为类型和变量使用相同的名称。
不给不同的东西起不同的名字是个坏主意(不仅在编程中):
我亲爱的注释者已经提到了行为观察者的学术原因。
为了给出明确的建议,命名不同的事物(这里:变量类型和变量实例):
typedef struct {
...
} X;
void foo() {
X *x = malloc(sizeof(X));
}
编写此示例的更灵活的方法是(正如 Shahbaz 的评论中已经提到的):
typedef struct {
...
} X;
void foo() {
X *x = malloc(sizeof(*x));
}
后一个示例允许您在x
不更改执行分配的代码的情况下更改类型。
这种方法的缺点是您可以在x
没有编译器通知的情况下从使用对数组的引用和 verse vica (作为类型 for )切换,并破坏您的代码这样做。