c - 具有灵活数组成员的结构体的 “Array”

标签 c casting c99 flexible-array-member

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

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

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

我的目标是C99,一次插入C11。

最佳答案

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

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

关于c - 具有灵活数组成员的结构体的 “Array”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59435697/

相关文章:

c - 为什么memset在函数上的工作方式不同?

使用包装函数调用 Malloc

c - 这就是我在 Windows 中使自定义控件透明且无闪烁的方法吗?或者我的这些步骤之一是错误的?

c - 文件处理在代码块中不起作用,但在 Turbo C++ 中很好

c - 原始 LWIP 将 TCP 传输发送到静态 IP

c - timespec 的存储大小未知

java - java中泛型类中的double方法

c# - MSDN 提供的 Equals 覆盖中的奇怪转换

android - Android中将两个float和integer类型的值相加的方法

c - 不同类型的链表