我正在用C语言编写一些非常重复的代码(阅读XML),我发现编写代码就像在构造函数中复制和粘贴代码一样容易*:
something_t* something_new(void)
{
something_t* obj = malloc(sizeof(*obj));
/* initialize */
return obj;
}
我想知道的是,当我刚定义sizeof(*obj)
时,使用这样的obj
是安全的吗? GCC没有显示任何警告,代码工作正常,但GCC往往有“有用”的扩展,所以我不相信它。
*是的,我知道我应该编写一个Python程序来编写我的C程序,但它几乎已经完成了。
答案 0 :(得分:1)
something_t* obj = malloc(sizeof(*obj));
我想知道的是,使用
sizeof(*obj)
是安全的 像这样,我刚刚定义obj
?
您的声明包含:
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 []'的大小。