真的需要灵活的数组成员吗? [英] Are flexible array members really necessary?

查看:23
本文介绍了真的需要灵活的数组成员吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个具有灵活数组成员的结构显然不是为了声明,而是与指向该结构的指针结合使用.声明灵活数组成员时,必须至少有一个其他成员,并且灵活数组成员必须是该结构中的最后一个成员.

A struct with a flexible array member, apparently, is not intended to be declared, but rather used in conjunction with a pointer to that struct. When declaring a flexible array member, there must be at least one other member, and the flexible array member must be the last member in that struct.

假设我有一个看起来像这样的:

Let's say I have one that looks like this:

struct example{
    int n;
    int flm[]; 
}

然后要使用它,我必须声明一个指针并使用 malloc 为结构的内容保留内存.

Then to use it, I'll have to declare a pointer and use malloc to reserve memory for the structure's contents.

struct example *ptr = malloc(sizeof(struct example) + 5*sizeof(int)); 

也就是说,如果我希望我的 flm[] 数组包含五个整数.然后,我可以使用我的结构像这样:

That is, if I want my flm[] array to hold five integers. Then, I can just use my struct like this:

ptr->flm[0] = 1; 

我的问题是,我不应该只使用指针而不是这个吗?它不仅兼容 C99 之前的版本,而且我可以在有或没有指向该结构的指针的情况下使用它.考虑到我已经必须在 flm 中使用 malloc,我不应该只能这样做吗?

My question is, shouldn't I be able to just use a pointer instead of this? Not only would it be compatible pre-C99, but I could use it with or without a pointer to that struct. Considering I already have to use malloc with the flm, shouldn't I just be able to do this?

考虑示例结构的这个新定义;

Consider this new definition of the example struct;

struct example{
    int n; 
    int *notflm; 
}

struct example test = {4, malloc(sizeof(int) * 5)}; 

我什至可以像灵活的数组成员一样使用替换:

I'd even be able to use the replacement the same way as the flexible array member:

这也行吗?(提供上述例子的定义与notflm)

Would this also work? (Provided the above definition of example with notflm)

struct example test; 
test.n = 4; 
notflm = malloc(sizeof(int) * 5); 

推荐答案

指针不是数组.选择使用哪个的基本原因与使用数组与指针时总是一样.在灵活数组成员的特殊情况下,以下是您可能更喜欢它们而不是指针的一些原因:

Pointers are not arrays. The basic reasons for choosing which to use are the same as they always are with arrays versus pointers. In the special case of flexible array members, here are some reasons you may prefer them over a pointer:

  • 减少存储要求.指针会将您的结构扩大(通常)4 或 8 个字节,如果您单独分配指向的存储而不是一次调用 malloc,您将花费更多的开销.

  • Reducing storage requirements. A pointer will enlarge your structure by (typically) 4 or 8 bytes, and you'll spend much more in overhead if you allocate the pointed-to storage separately rather than with a single call to malloc.

提高访问效率.一个灵活的阵列成员位于与结构底座的恒定偏移量处.一个指针需要一个单独的解引用.这会影响访问它所需的指令数量和注册压力.

Improving access efficiency. A flexible array member is located at a constant offset from the structure base. A pointer requires a separate dereference. This affects both number of instructions required to access it, and register pressure.

分配成功/失败的原子性.如果您分配结构并为其分配存储以指向两个单独的步骤,则在失败情况下用于清理的代码将更加丑陋,因为您有一个成功而另一个失败的情况.这可以通过一些指针算法来避免,以从相同的 malloc 请求中分割出两者,但由于对齐问题,很容易弄错逻辑并调用 UB.

Atomicity of allocation success/failure. If you allocate the structure and allocate storage for it to point to as two separate steps, your code for cleaning up in the failure cases will be much uglier, since you have the case where one succeeded and the other failed. This can be avoided with some pointer arithmetic to carve both out of the same malloc request, but it's easy to get the logic wrong and invoke UB due to alignment issues.

避免深度复制的需要.如果使用灵活数组而不是指针,则可以简单地使用 memcpy(不赋值,因为赋值无法知道灵活数组长度)来复制结构,而不必也复制指向的数据并修复指针在新副本中.

Avoiding need for deep-copy. If you use a flexible array instead of a pointer, you can simply memcpy (not assign, since assignment can't know the flexible array length) to copy the structure rather than having to copy the pointed-to data too and fix up the pointer in the new copy.

避免对 deep-free 的需求.能够只free 单个对象而不是free 指向的数据是非常方便和干净的.当然,这也可以通过上面提到的分割单个 malloc"方法来实现,但灵活的数组使其更容易且不易出错.

Avoiding need for deep-free. It's very convenient and clean to be able to just free a single object rather than having to free pointed-to data too. This can also be achieved with the "carving up a single malloc" approach mentioned above, of course, but flexible arrays make it easier and less error-prone.

当然还有更多原因......

Surely many more reasons...

这篇关于真的需要灵活的数组成员吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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