3

在这段代码中,为什么是sizeof(x)指针的大小,而不是类型的大小x

typedef struct {
  ...
} x;

void foo() {
  x *x = malloc(sizeof(x));
}
4

3 回答 3

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);
于 2012-06-10T11:48:19.807 回答
5

这是因为sizeof(x)使用了 的最内层定义x,即指针。为避免此问题,请不要为类型和变量使用相同的名称。

于 2012-06-10T11:34:32.547 回答
0

不给不同的东西起不同的名字是个坏主意(不仅在编程中):

我亲爱的注释者已经提到了行为观察者的学术原因。

为了给出明确的建议,命名不同的事物(这里:变量类型和变量实例):

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 )切换,并破坏您的代码这样做。

于 2012-06-10T11:57:55.177 回答