如何使用灵活的数组成员初始化结构 [英] How to initialize a structure with flexible array member

查看:25
本文介绍了如何使用灵活的数组成员初始化结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下结构

typedef struct _person {
    int age;
    char sex;
    char name[];
}person;

关于如何在不使用 malloc() 的情况下使用灵活的数组成员创建实例和初始化结构,我已经做了一些基本的互联网搜索(但没有成功).

I have done some basic internet search (but unsuccessful) on how to create an instance and initialize a structure with a flexible array member without using malloc().

例如:对于像

struct a {
    int age; 
    int sex;
};

我们可以创建一个struct a的实例并像这样初始化它

We can create an instance of struct a and initialize it like

struct a p1 = {10, 'm'};

但是对于包含灵活数组的结构(如上面提到的_person),我们如何创建一个实例并像我们对普通结构那样进行初始化?

But for structures with flexible array in it (like _person as mentioned above) how can we create an instance and initialize like how we do it for normal structures?

有可能吗?如果是这样,我们如何在初始化时传递数组大小和要初始化的实际值?

Is it even possible? If so, how do we pass the array size during the initialization and the actual value to be initialized?

(或)

创建具有灵活数组的结构的唯一方法是使用 C99 规范中提到的 malloc() - 6.7.2.1 结构和联合说明符 - 点 #17?!

Is it true that the only way to create a structure with flexible array is using malloc() as mentioned in C99 specification - 6.7.2.1 Structure and union specifiers - point #17?!

推荐答案

不,必须始终手动分配灵活数组.但是你可以使用 calloc 来初始化灵活部分和一个复合文字来初始化固定部分.我会将它包装在一个分配 inline 函数中,如下所示:

No, flexible arrays must always be allocated manually. But you may use calloc to initialize the flexible part and a compound literal to initialize the fixed part. I'd wrap that in an allocation inline function like this:

typedef struct person {
  unsigned age;
  char sex;
  size_t size;
  char name[];
} person;

inline
person* alloc_person(int a, char s, size_t n) {
  person * ret = calloc(sizeof(person) + n, 1);
  if (ret) memcpy(ret,
                  &(person const){ .age = a, .sex = s, .size = n},
                  sizeof(person));
  return ret;
}

请注意,如果分配成功,调用者将检查这是否成功.

Observe that this leaves the check if the allocation succeeded to the caller.

如果您不需要我在此处包含的 size 字段,那么宏甚至就足够了.只是在执行 memcpy 之前不可能检查 calloc 的返回.在我迄今为止编写的所有系统下,这将相对较好地中止.一般我认为 malloc<的返回/code> 是次要的,但在这个主题上意见分歧很大.

If you don't need a size field as I included it here, a macro would even suffice. Only that it would be not possible to check the return of calloc before doing the memcpy. Under all systems that I programmed so far this will abort relatively nicely. Generally I think that return of malloc is of minor importance, but opinions vary largely on that subject.

这可能(在那种特殊情况下)为优化器提供更多机会将代码集成到环境中:

This could perhaps (in that special case) give more opportunities to the optimizer to integrate the code in the surroundings:

#define ALLOC_PERSON(A,  S,  N)                                 
((person*)memcpy(calloc(sizeof(person) + (N), 1),               
                 &(person const){ .age = (A), .sex = (S) },     
                 sizeof(person)))

AS 是编译时常量时,这可能比函数更好.在这种情况下,复合文字,因为它是 const 限定的,可以静态分配,并且可以在编译时完成其初始化.此外,如果代码中出现多个具有相同值的分配,则编译器只能实现该复合文字的一个副本.

The case that this could be better than the function is when A and S are compile time constants. In that case the compound literal, since it is const qualified, could be allocated statically and its initialization could be done at compile time. In addition, if several allocations with the same values would appear in the code the compiler would be allowed to realize only one single copy of that compound literal.

这篇关于如何使用灵活的数组成员初始化结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆