标签: flexible-array-member

在另一个结构中具有灵活数组成员的结构

以下代码有效吗?

struct foo {
    int a;
    int b[];
};

struct bar {
    int c;
    struct foo d;
};

struct bar *x = malloc(sizeof(struct bar) + sizeof(int [128]));
Run Code Online (Sandbox Code Playgroud)

对我来说似乎没问题,但我有点怀疑,因为如果我这样做,编译器不会抱怨:

struct bar {
    struct foo d;
    int c;
};
Run Code Online (Sandbox Code Playgroud)

c flexible-array-member

3
推荐指数
1
解决办法
891
查看次数

收到以下警告:在 GCC 4.4 中使用灵活数组成员传递结构的 ABI 已更改

当我尝试运行我的程序时,我收到了这个警告和一些奇怪的错误。 rmi_pdu在下面的结构中包含一个我想访问的可变大小的数组。

struct rmi_message_s {  /* Queue element containing Rmi message */
  struct rmi_message_s          *hnext;
  struct rmi_message_s          *hprev;
  uint16_t                      gen_counter;   /* Generation counter */
  time_value                    send_time;
  uint8_t                       retry_count;
  TAILQ_ENTRY(rmi_message_s)    rmi_message_next;
  rmi_message_pdu               rmi_pdu; /* contains a variable sized array */ 
};

typedef struct {
  uint16_t        zero;
  uint16_t        type;
  uint8_t         version;
  uint8_t         len;
  uint8_t         protocol;
  uint16_t        edge_port;
  uint16_t        core_port;
  uint32_t        connexus_id;
  pi_ipv4_addr_t  edge_addr;
  pi_ipv4_addr_t  core_addr;
  uint16_t        gen_count;     /* Integer to identify a stale packet */
  uint8_t         payload[];
} rmi_message_pdu;
Run Code Online (Sandbox Code Playgroud)

问题是当我试图释放我动态分配的内存时。内容在那里,但free() …

c flexible-array-member

2
推荐指数
1
解决办法
3591
查看次数

改变结构的大小?

我创建了一个名为Register的结构,其中包含大约8个字段.我现在想要创建一个名为Instrument的结构,它应该具有可变数量的字段,6对于每个乐器都是相同的,加上一定数量的字段取决于归属于它的寄存器数量.我该如何创建呢?

为清楚起见,这是我想要创建的内容(虽然可能不准确).

    typedef struct {
   int    x;
   int    y;
   int    z;
} Register;

 typedef struct {
       int    x;
       int    y;
       int    z;
       Register Reg1;
       Register Reg2;
       ...
    } Instrument;
Run Code Online (Sandbox Code Playgroud)

c structure flexible-array-member

2
推荐指数
1
解决办法
51
查看次数

如果编译器定义__STDC_NO_VLA__,它是否还需要支持灵活的数组成员?

在C99中,灵活的阵列成员(结构)和可变长度数组是标准的强制性部分 - 符合C99的编译器(实现)必须同时支持它们.

在C11中,允许实现定义(§6.10.8.3条件特征宏):

__STDC_NO_VLA__ 整数常量1,用于指示实现不支持可变长度数组或可变修改类型.

我没有发现标准中的任何地方规定具有FAM的结构是可变修改类型,因此我认为即使不支持VLA,也需要C11编译器来支持FAM.赞成这种解释的一个项目:具有FAM的结构的大小是固定的; FAM不计入大小的一部分(而VLA的大小不是编译时常量).

c language-lawyer variable-length-array flexible-array-member c11

2
推荐指数
2
解决办法
259
查看次数

是否允许返回具有灵活数组成员的结构?

GCC 编译函数返回具有灵活数组成员的结构。标准在 6.7.2.1 中给出了如何处理此类结构的定义:

在大多数情况下,灵活数组成员会被忽略。特别是,该结构的大小就像省略了柔性阵列成员一样,只是它可能具有比省略所暗示的更多的尾部填充。

由于具有灵活数组成员的结构的大小已知,因此根据 6.2.5 中给出的完整性定义,类型是完整的:

在翻译单元内的各个点,对象类型可能是不完整的(缺乏足够的信息来确定该类型的对象的大小)或完整的(具有足够的信息)。37)

另外,6.5.2.2

表示被调用函数 96) 的表达式应具有指向返回 void 或返回除数组类型之外的完整对象类型的函数的类型指针。

因此返回具有灵活数组成员的 s 应该是合法的struct


如何修复下面的示例以使其正常工作(我需要具有灵活数组成员的堆栈分配结构):

#include <stdio.h>

struct test{
    size_t sz;
    char data[];
};

struct test get_test(void){
    int sz = 5;
    char data[5] = "test";
    struct test test = {.sz = 5};
    //How to copy char data[5] into the struct test test?
    return test;
}

int main(void){
    struct test tst = get_test();
    printf("%s\n", tst.data);
}
Run Code Online (Sandbox Code Playgroud)

c arrays language-lawyer flexible-array-member

2
推荐指数
1
解决办法
699
查看次数

在内存分配之前对灵活成员数组的第一个元素使用 sizeof 是未定义行为?

如果我们有具有灵活成员数组的结构,例如:-

struct test{
    int n;
    int b[];
};
Run Code Online (Sandbox Code Playgroud)

然后,即使在 malloc 完成之前,如果我们尝试打印:-

struct test t;
printf("%lu",sizeof(t.b[0]);
Run Code Online (Sandbox Code Playgroud)

这属于未定义行为吗?

C99 是这样描述灵活成员数组的:-

“如果这个数组没有元素,它的行为就好像它有一个元素一样,但如果尝试访问该元素或生成一个超过该元素的指针,则该行为是未定义的。”

因此,访问b[0]是未定义的行为,但它是否也适用于 sizeof 运算符,因为它是编译时运算符并且t.b[0]在运行时永远不会在这里访问?

当我在 gcc 编译器中尝试这个时,我输出了 4 个字节,但如果它属于未定义的行为,那么我们不能认为这个输出是理所当然的,除非 gcc 给出了一些扩展,在这种情况下我不确定。

c structure sizeof c99 flexible-array-member

2
推荐指数
1
解决办法
70
查看次数

如何正确使用灵活数组成员?

这是我声明的类型:(
我也t_sphere声明了)t_cylindert_triangle

typedef struct  s_intersection{
  double       t1;
  double       t2;
  int id;
  union {
    t_sphere sph;
    t_cylinder cyl;
    t_triangle tri;
  } u[];
} t_intersection;
Run Code Online (Sandbox Code Playgroud)

要引用结构体中的联合变量,我必须提前知道它是什么类型。这是可能的,这要归功于我的结构中声明的 id int,但是用我想到的方法来实现它是非常繁重的。
这是我编写的用于分配 t_intersection 变量的函数:

t_intersection  *intersection(unsigned int geometric_figure_id, void *figure)
{
    t_intersection  *p;

    if (geometric_figure_id == SPHERE_ID)
        p = malloc(sizeof(*p) + sizeof (p->u[0].sp));
    else if (geometric_figure_id == CYLINDER_ID)
        p = malloc(sizeof(*p) + sizeof (p->u[0].cy));
    else if (geometric_figure_id == TRIANGLE_ID)
        p = malloc(sizeof(*p) + sizeof (p->u[0].tr));
    if (p == NULL)
        return (NULL); …
Run Code Online (Sandbox Code Playgroud)

c unions flexible-array-member

2
推荐指数
1
解决办法
179
查看次数

创建大小为零的灵活数组成员是否合法?

C99标准允许创建灵活的阵列成员,例如

typedef struct pstring {
  size_t length;
  char   string[];
} pstring;
Run Code Online (Sandbox Code Playgroud)

然后用类似的东西初始化pstring* s = malloc(sizeof(pstring) + len).len为零是允许的吗?它似乎是一致的,并且不时地节省空间(pstring当然可能不是这个例子).另一方面,我不知道下面的代码会做什么:

pstring* s = malloc(sizeof(pstring));
s->string;
Run Code Online (Sandbox Code Playgroud)

这看起来似乎可能适用于一个编译器而不是另一个编译器,或者在一个操作系统而不是另一个操作系统上,或者在某一天而不是另一个,所以我真正想知道的是标准对此的说法.这是malloc示例代码中未定义的行为,还是仅对其s->string无效的访问,还是完全不同的其他内容?

c struct c99 flexible-array-member

1
推荐指数
1
解决办法
418
查看次数

使用模板和基类实现灵活的数组成员

在C99中,您通常会看到以下模式:

struct Foo {
    int var1;
    int var2[];
};

Foo * f = malloc(sizeof(struct Foo) + sizeof(int)*n);
for (int i=0; i<n; ++i) {
    f->var2[i] = p;
}
Run Code Online (Sandbox Code Playgroud)

但不仅是这个糟糕的C++,它也是非法的.

您可以在C++中实现类似的效果,如下所示:

struct FooBase {
    void dostuff();

    int var1;
    int var2[1];
};

template<size_t N>
struct Foo : public FooBase {
    int var2[N-1];
};
Run Code Online (Sandbox Code Playgroud)

虽然这将工作(你可以访问FooBase的方法var2[2],var2[3]等等),它依赖于Foo作为标准配置,这是不是很漂亮.

这样做的好处是非模板化函数可以Foo*通过采用FooBase*和调用操作的方法来接收任何没有转换的函数var2,并且内存是连续的(这可能是有用的).

有没有更好的方法来实现这一点(这是合法的C++/C++ 11/C++ 14)?

我对两个简单的解决方案不感兴趣(包括基类中的额外指针到数组的开头,并在堆上分配数组).

c++ flexible-array-member

1
推荐指数
1
解决办法
2544
查看次数

未命名结构的灵活数组成员

考虑以下示例:

typedef struct test_flex_arr{
    size_t sz;
    struct {
        int i;
        const char *path;
    } info[];
} tfa;

int main(void){
    size_t sz = 100;
    tfa *ptr = malloc(sizeof *ptr + sizeof (*((tfa*) NULL)).info[sz]);
    ptr->info[99].i = 10;
    printf("%d\n", ptr->info[99].i); //prints 10
}
Run Code Online (Sandbox Code Playgroud)

演示

我预计该程序会崩溃,但运行得很好。如指定6.5.3.4(p2)

sizeof操作者产生其操作数的大小(以字节为单位),其可以是表达或类型的括号名称。大小由操作数的类型确定。结果是一个整数。如果操作数的类型是可变长度数组类型,则对操作数求值;否则,不评估操作数,结果为整数常量

操作数的类型sizeof ((*((tfa*) NULL)).info)[sz]是可变长度数组,因此应求值该操作数。但是对操作数的求值意味着取消引用NULL,我期望这会导致崩溃。

代码的行为是否定义正确?

c language-lawyer flexible-array-member

1
推荐指数
1
解决办法
81
查看次数

什么是结构中的灵活数组成员?

我正在用 C 编写数组列表。

我针对通用标头定义了一个特定于实现的结构。

struct array_list_env {
    void **array;    // pointer to the array
    size_t capacity; // length of the array
    size_t size;     // number of occupied elements in the array
}
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试将其更改void **arrayvoid *array[]我得到的

错误:灵活的数组成员不在结构的末尾

什么是灵活数组成员?

c flexible-array-member

1
推荐指数
1
解决办法
56
查看次数

初始化结构并通过引用传递

我是C的新手,我在使用结构时遇到了麻烦.我有以下代码:

typedef struct uint8array {
 uint8 len;
 uint8 data[];
} uint8array;

int compare_uint8array(uint8array* arr1, uint8array* arr2) {
  printf("%i %i\n data: %i, %i\n", arr1->len, arr2->len, arr1->data[0], arr2->data[0]);
  if (arr1->len != arr2->len) return 1;
  return 0;
  }

int compuint8ArrayTest() {
 printf("--compuint8ArrayTest--\n");
 uint8array arr1;
 arr1.len = 2;
 arr1.data[0] = 3;
 arr1.data[1] = 5;    

 uint8array arr2;
 arr2.len = 4;
 arr2.data[0] = 3;
 arr2.data[1] = 5;    
 arr2.data[2] = 7;    
 arr2.data[3] = 1;    

 assert(compare_uint8array(&arr1, &arr2) != 0);
}
Run Code Online (Sandbox Code Playgroud)

现在这个程序的输出是:

 --compuint8ArrayTest--
 3 4
 data: 5, 3
Run Code Online (Sandbox Code Playgroud)

为什么值不是我初始化它们的值?我在这里错过了什么?

c struct flexible-array-member

0
推荐指数
1
解决办法
40
查看次数

如何在C++中处理灵活的数组

上下文

所以我一直在玩C/C++中的数组,试图创建可以动态添加和删除元素的数组.

当然,我认为C语言中的灵活数组成员特征是合适的方式.所以我开始尝试,因为下面的代码显示:

#include <cstdio> // printing stuff
#include <stdlib.h> // memory allocation stuff

// The array type
template <typename structType>
struct Array {
    private:
        // The structure containing the F.A.M.
        struct ArrayStructure { size_t length = 0; structType array[]; }
            *arrayStructurePointer, arrayStructure;
        constexpr inline static void add() {}

    public:
        // Constructor
        template <typename... types, typename = structType>
        explicit Array(types... elements) {
            this -> arrayStructurePointer =
                (ArrayStructure*) malloc(sizeof(structType));
            this -> arrayStructurePointer = &(this -> arrayStructure);
            this -> add(elements...);
        }

        // …
Run Code Online (Sandbox Code Playgroud)

c++ memory-management flexible-array-member

0
推荐指数
1
解决办法
143
查看次数