灵活的阵列成员真的有必要吗? [英] Are flexible array members really necessary?

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

问题描述

具有灵活的阵列成员的结构,显然不打算声明,但结合使用,而用一个指针结构。当声明一个灵活的阵列成员,必须有至少一个其他成员,以及灵活的阵列成员必须是在结构中的最后一个成员。

让我们说我有一个看起来是这样的:

 结构例如{
    INT N;
    INT FLM [];
}

然后用它,我必须声明指针和使用malloc保留内存结构的内容。

 结构例子* PTR =的malloc(sizeof的(例如结构)+ 5 *的sizeof(INT));

也就是说,如果我想我的FLM []数组保存五个整数。然后,我就可以用我的结构
像这样的:

  ptr-> FLM [0] = 1;

我的问题是,我不应该能够只使用一个指针来代替呢?它不仅会兼容pre-C99,但我可以带或不带一个指向该结构使用它。
考虑到我已经具备了使用malloc与FLM,不应该只是我能做到这一点?

考虑例子结构的新定义;

 结构例如{
    INT N;
    INT * notflm;
}例如结构测试= {4,的malloc(sizeof的(INT)* 5)};

我甚至可以使用替换方式一样灵活的阵列成员:

这会还工作吗? (例如提供与notflm的上述定义)

 结构示例测试;
test.n = 4;
notflm =的malloc(sizeof的(INT)* 5);


解决方案

指针不是数组。对于选择的基本原因而使用是相同的,因为它们总是与阵列与指针。在灵活的数组成员的特殊情况下,这里有一些原因,你可以在一个指针preFER他们:


  • 减少存储需求。指针将(典型值)4个或8个字节放大你的结构,如果你分配你会花更多的开销中所指向的存储分开,而不是一个调用的malloc


  • 提高访问效率。灵活的数组成员位于恒定从结构基本偏移。指针需要一个单独的反引用。这会影响既要求数量的指令来访问它,并注册pressure。


  • 分配成功/失败的原子。如果分配结构和分配存储它指向作为两个单独的步骤,您的code在失败的案例清理将变得丑陋,因为你有其中一个成功和失败等的情况。这可以用一些指针运算避免瓜分既出相同的的malloc 的要求,但它很容易得到逻辑错误并调用UB由于对齐的问题。


  • 避免需要进行深拷贝。如果你使用一个灵活的阵列,而不是一个指针,你可以简单的memcpy(不分配,因为分配可以不知道柔性阵列长度)来复制结构,而不是复制指针指向的数据也和修复了指针在新副本。


  • 避免需要进行深免费。这是非常方便,清洁,能够公正免费单个对象,而不必免费指向的数据量太大。这也可以用瓜分一个的malloc 的方法上面提到的,当然,实现的,但灵活的阵列使其更容易,更容易出错。


  • 当然,还有更多的理由...


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[]; 
}

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)); 

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; 

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:

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:

  • 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.

  • 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.

  • 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.

  • 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天全站免登陆