`something_t * x = malloc(sizeof(* x))`有什么问题吗?

时间:2014-12-11 23:26:15

标签: c gcc malloc sizeof

我正在用C语言编写一些非常重复的代码(阅读XML),我发现编写代码就像在构造函数中复制和粘贴代码一样容易*:

something_t* something_new(void)
{
    something_t* obj = malloc(sizeof(*obj));
    /* initialize */
    return obj;
}

我想知道的是,当我刚定义sizeof(*obj)时,使用这样的obj是安全的吗? GCC没有显示任何警告,代码工作正常,但GCC往往有“有用”的扩展,所以我不相信它。

*是的,我知道我应该编写一个Python程序来编写我的C程序,但它几乎已经完成了。

3 个答案:

答案 0 :(得分:1)

something_t* obj = malloc(sizeof(*obj));
     

我想知道的是,使用sizeof(*obj)是安全的   像这样,我刚刚定义obj

您的声明包含:

  • type-specifier something_t
  • 声明者 * obj
  • =
  • 初始化程序 malloc(sizeof(*obj))
  • ;

C标准在标识符范围

部分中说明
  

结构,联合和枚举标记的范围从一开始就是   在声明了的类型说明符中出现标记之后   标签。每个枚举常量的范围都在此之后开始   枚举器列表中定义的枚举器的外观。任何其他   identifier具有在其完成之后开始的范围   说明符。

由于obj 的范围在其声明符完成之后开始,因此标准保证初始化程序中使用的标识符指的是刚刚定义的对象。

答案 1 :(得分:0)

虽然我们给出了像这样的尺寸。

something_t* obj = malloc(sizeof(obj));

它会将内存分配给该指针变量为四个字节(分配给指针变量的字节。)

something_t* obj = malloc(sizeof(*obj));

它将采用声明为该指针的数据类型。

例如,

char *p;
printf("%d\n",sizeof(p));

它会将值返回为四。

printf("%d\n",sizeof(*p));

现在它将返回值为1。这是分配给角色的字节。因此,当我们在sizeof中使用* p时,它将采用数据类型。我不知道这是你期待的答案。

答案 2 :(得分:0)

这很安全。例如,

n = sizeof(*(int *)NULL);

在这种情况下,不会发生NULL指针访问,因为编译器可以在运行时不知道“*(int *)NULL”的值的情况下计算操作数的大小。

C89 / 90标准保证'sizeof'表达式是常数;它被转换为常量(例如0x04)并在编译阶段嵌入到二进制代码中。

在C99标准中,'sizeof'表达式并不总是编译时常量,因为引入了可变长度数组。例如,

n = sizeof(int [*(int *)NULL]);

在这种情况下,需要在运行时知道“*(int *)NULL”的值来计算'int []'的大小。