【问题标题】:“Array” of struct with flexible array member具有灵活数组成员的结构的“数组”
【发布时间】:2020-04-13 14:01:03
【问题描述】:

我正在重写一些具有结构数组的旧代码,每个结构都有一个数组成员,其长度在编译时是固定的。外部数组中的结构数在编译时确定以适合(典型)内存页面。我想在运行时创建内部数组变量,但保持“外部数组适合页面”逻辑完整(并使用sysconf(_SC_PAGESIZE) 精确获取页面大小)。所以我的结构有一个灵活的数组成员

struct foo_t 
{
  bar_t *bar;
  float baz[];
};

我想要这些东西的数组,但当然这是不允许的。但是所有这些结构都将具有相同大小的灵活数组成员(由运行时确定),所以我可以使用它们的“数组”来代替吗?也就是说,有一个char * 有足够的空间来容纳它们中的n 个,自己进行偏移计算,并将指针偏移量转换为foo_t *,然后访问、修改、 等。

我的目标是 C99,C11 在推。

【问题讨论】:

  • 改用指向结构的指针数组。
  • Some-programmer-dude:关键是我希望结构本身在同一页面中(涉及很多结构间计算)
  • 那么你需要手动进行内存管理。也许一页用于实际结构及其数据,那么您可以将一组指针指向该页吗?只是不要忘记对齐问题。
  • 您要更改结构体大小运行时吗? (我的意思是要调整它的大小?)
  • 结构的大小意味着将指针放在同一个页面中应该是可行的,并且有一个带有自己的可变长度成员的外部结构来保存它们。这听起来值得测试实现,我来看看。但是我的直觉告诉我,拥有这些指针实际上只是将指针算术转换为指针取消引用,后者的成本更高,与我的“男孩赛车手”天性相反 :-)

标签: c casting c99 flexible-array-member


【解决方案1】:

C 标准不支持这一点。在实践中,您可以计算运行时结构大小和元素位置:

#include <stddef.h>


typedef struct Unknown bar_t;


struct foo_t
{
    bar_t *bar;
    float baz[];
};


/*  Calculate the size required for an array of struct foo_t objects in which
    each flexible array member has NElements elements.
*/
size_t SizeOfFoo(size_t NElements)
{
    /*  Create an unused pointer to provide type information, notably the size
        of the member type of the flexible array.
    */
    struct foo_t *p;

    /*  Calculate the size of a struct foo_t plus NElements elements of baz,
        without padding after the array.
    */
    size_t s = offsetof(struct foo_t, baz) + NElements * sizeof p->baz[0];

    //  Calculate the size with padding.
    s = ((s-1) / _Alignof(struct foo_t) + 1) * _Alignof(struct foo_t);

    return s;
}


/*  Calculate the address of the element with index Index in an “array” built
    of struct foo_t objects in which each flexible array member has NElements
    elements.
*/
struct foo_t *SubscriptFoo(void *Base, size_t NElements, ptrdiff_t Index)
{
    return (struct foo_t *) ((char *) Base + Index * SizeOfFoo(NElements));
}

这可能存在一些语言律师问题,但我不认为它们会影响实际的编译器。

【讨论】:

  • 这正是我引用“数组”的意思,感谢有关精确大小计算的详细信息,我看到它在 P99 宏集合中,但在那里:-)。
猜你喜欢
  • 1970-01-01
  • 2012-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 2011-03-04
  • 2019-10-21
相关资源
最近更新 更多