结构体内指针的初始化内存分配(C99)

4
假设我们有一个类型:
typedef struct __BUFF_T__
{
    u_int8_t *buf;
    u_int32_t size;
}buff_t;

在C99中分配内存的方式是否正确?
buff_t a = {.size = 20,.buf = calloc(a.size,1)};

编译器显示警告

在其自身初始化期间使用变量"data"时未初始化

内存可用,但是否有其他不产生警告的选项可以实现相同的效果?

2个回答

4

从6.7.9p23:

初始化列表表达式的求值在彼此之间是不确定顺序的[...](152)特别地,求值顺序不必与子对象初始化的顺序相同。

因此,在评估a.buf的初始化期间评估calloc(a.size, 1)时,没有保证a.size已初始化。

在这种情况下,一个合适的初始化程序将是一个创建函数:

inline buff_t create_buff(u_int32_t size) {
  return (buff_t) {.size = size, .buf = calloc(size, 1)};
}
buff_t a = create_buff(20);

这不能用于静态或文件范围的对象;在这种情况下需要使用宏(或者例如gcc语句表达式,可以用于宏)。


3

在分配了a之后,结构体的初始化才会完全完成,因为您不知道表达式将按什么顺序评估。

如果您需要使用结构体字段来初始化同一结构体中的另一个字段,则必须分步执行。


我认为这个答案是错误的,特别是这句话:因为你不知道字段的初始化顺序。C语言规定初始化应按照初始化列表顺序进行。但正如@ecatmur所指出的那样,C语言也规定初始化列表表达式的求值在彼此之间是不确定顺序的,这就是为什么这里是未指明的原因。 - ouah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接