The*_*nic 12 c struct flexible-array-member
显然,具有灵活数组成员的结构不是要声明的,而是与指向该结构的指针一起使用.声明灵活的数组成员时,必须至少有一个其他成员,并且灵活数组成员必须是该结构中的最后一个成员.
假设我有一个看起来像这样的:
struct example{
int n;
int flm[];
}
Run Code Online (Sandbox Code Playgroud)
然后要使用它,我将必须声明一个指针并使用malloc为结构的内容保留内存.
struct example *ptr = malloc(sizeof(struct example) + 5*sizeof(int));
Run Code Online (Sandbox Code Playgroud)
也就是说,如果我希望我的flm []数组保持五个整数.然后,我可以像这样使用我的结构:
ptr->flm[0] = 1;
Run Code Online (Sandbox Code Playgroud)
我的问题是,我不应该只使用指针而不是这个吗?它不仅在C99之前兼容,而且我可以在有或没有指向该结构的指针的情况下使用它.考虑到我已经必须将malloc与flm一起使用,我不应该只能这样做吗?
考虑示例结构的这个新定义;
struct example{
int n;
int *notflm;
}
struct example test = {4, malloc(sizeof(int) * 5)};
Run Code Online (Sandbox Code Playgroud)
我甚至可以像柔性阵列成员一样使用替换:
这也有用吗?(如上面的示例定义为notflm)
struct example test;
test.n = 4;
notflm = malloc(sizeof(int) * 5);
Run Code Online (Sandbox Code Playgroud)
R..*_*R.. 26
指针不是数组.选择使用哪个的基本原因与数组与指针一样.在灵活数组成员的特殊情况下,以下是您可能更喜欢它们而不是指针的一些原因:
降低存储要求.指针将通过(通常)4或8个字节扩大您的结构,如果您单独分配指向存储而不是单次调用,您将在开销上花费更多malloc
.
提高访问效率.柔性阵列构件位于与结构基座恒定的偏移处.指针需要单独的解引用.这会影响访问它所需的指令数量和注册压力.
分配成功/失败的原子性.如果您分配结构并为其分配存储以指向两个单独的步骤,那么在故障情况下清理的代码将会更加丑陋,因为您遇到了一个成功而另一个成功的情况.这可以通过一些指针算法来避免同一个malloc
请求中的两个,但是由于对齐问题很容易导致逻辑错误并调用UB.
避免需要深层复制.如果你使用一个灵活的数组而不是一个指针,你可以简单地memcpy(不分配,因为赋值不能知道灵活的数组长度)来复制结构,而不是必须复制指向的数据并修复指针在新副本中.
避免深度自由的需要.能够只free
使用一个对象而不必free
指向数据非常方便和干净.当然,这也可以通过malloc
上面提到的"单独划分"方法来实现,但是灵活的阵列使其更容易且更不容易出错.
当然还有更多原因......