标签: flexible-array-member

灵活的阵列成员真的有必要吗?

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

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

struct example{
    int n;
    int flm[]; 
}
Run Code Online (Sandbox Code Playgroud)

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

struct example *ptr = malloc(sizeof(struct example) + 5*sizeof(int)); 
Run Code Online (Sandbox Code Playgroud)

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

ptr->flm[0] = 1; 
Run Code Online (Sandbox Code Playgroud)

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

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

struct example{
    int n; 
    int *notflm; 
}

struct example test = {4, malloc(sizeof(int) * 5)}; 
Run Code Online (Sandbox Code Playgroud)

我甚至可以像柔性阵列成员一样使用替换:

这也有用吗?(如上面的示例定义为notflm)

struct example test; 
test.n = 4; 
notflm = malloc(sizeof(int) * 5); 
Run Code Online (Sandbox Code Playgroud)

c struct flexible-array-member

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

如何在C中推和弹出一个空指针

我有这个工作代码:

#import <stdlib.h>
#import <stdio.h>

typedef struct myarray {
  int len;
  void* items[];
} MYARRAY;

MYARRAY *collection;

void
mypop(void** val) {
  puts(collection->items[collection->len]);
  *val = collection->items[collection->len--];
}

void
mypush(void* val) {
  int len = collection->len++;
  collection->items[len] = val;
  puts(collection->items[len]);
}

int
main() {
  puts("Start");
  collection = malloc( sizeof *collection + (sizeof collection->items[0] * 1000) );
  collection->len = 0;
  puts("Defined collection");
  mypush("foo");
  puts("Pushed foo");
  mypush("bar");
  puts("Pushed bar");
  char str1;
  mypop((void*)&str1);
  puts("Popped bar");
  puts(&str1);
  char str2;
  mypop((void*)&str2);
  puts("Popped foo");
  puts(&str2);
  puts("Done");
  return 0; …
Run Code Online (Sandbox Code Playgroud)

c arrays void-pointers flexible-array-member

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

这个 C 程序是否定义了两个结构体定义,涉及一个灵活的数组成员?

具有灵活数组成员的结构是一种可以声明变量并sizeof可以应用变量的类型,这一事实会导致以下程序中出现异常行为。

\n

文件fam1.c

\n
#include <stdio.h>\n#include <stddef.h>\n\nstruct s {\n  char c;\n  char t[]; };\n\nextern struct s x;\n\nsize_t s_of_x(void);\n\nint main(void) {\n  printf("size of x: %zu\\n", sizeof x);\n  printf("size of x: %zu\\n", s_of_x());\n}\n
Run Code Online (Sandbox Code Playgroud)\n

文件fam2.c

\n
#include <stddef.h>\n\nstruct s {\n  char c;\n  char t[2]; };\n\nstruct s x;\n\nsize_t s_of_x(void) {\n  return sizeof x;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

该程序在编译和运行时会发出一些令人惊讶的输出:

\n
#include <stdio.h>\n#include <stddef.h>\n\nstruct s {\n  char c;\n  char t[]; };\n\nextern struct s x;\n\nsize_t s_of_x(void);\n\nint main(void) {\n  printf("size of x: %zu\\n", sizeof …
Run Code Online (Sandbox Code Playgroud)

c language-lawyer flexible-array-member c17

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

如何在rodata中初始化灵活数组并创建指向它的指针?

在C中,代码

char *c = "Hello world!";
Run Code Online (Sandbox Code Playgroud)

存储Hello world!\0在rodata中,并c使用指向它的指针进行初始化。除了字符串以外,我该如何处理?

具体来说,我正在尝试定义自己的字符串类型

typedef struct {
   size_t Length;
   char Data[];
} PascalString;
Run Code Online (Sandbox Code Playgroud)

然后想要某种宏,以便我可以说

const PascalString *c2 = PASCAL_STRING_CONSTANT("Hello world!");
Run Code Online (Sandbox Code Playgroud)

并且具有相同的行为,即\x0c\0\0\0Hello world!存储在rodata中,并c2使用指向它的指针进行初始化。

我尝试使用

#define PASCAL_STRING_CONSTANT(c_string_constant) \
    &((const PascalString) { \
        .Length=sizeof(c_string_constant)-1, \
        .Data=(c_string_constant), \
    })
Run Code Online (Sandbox Code Playgroud)

正如这些 问题中所建议的那样,但它不起作用,因为它Data是一个灵活的数组:我收到了错误error: non-static initialization of a flexible array member(对于gcc,clang给出了类似的错误)。

这在C中可能吗?如果是这样,PASCAL_STRING_CONSTANT宏将是什么样?

澄清

对于C字符串,以下代码块永远不会将字符串存储在堆栈中:

#include <inttypes.h>
#include <stdio.h>

int main(void) {
    const char *c = "Hello …
Run Code Online (Sandbox Code Playgroud)

c flexible-array-member storage-duration

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

如何在堆栈上分配具有灵活数组成员的结构

假设我们有一个以灵活数组成员结尾的结构:

struct foo {
    size_t len;
    uint8_t data[];
};
Run Code Online (Sandbox Code Playgroud)

如何在堆栈上分配这个结构(即内存在作用域结束时自动释放)?另外,如果len能包含字段的大小就更好了data

目前,我做的事情如下:

uint8_t buf[256];
struct foo *foo = (struct foo *)buf;
foo->len = sizeof(buf) - sizeof(struct foo);
Run Code Online (Sandbox Code Playgroud)

然而,它很容易出错。使用alloca()可能会稍微好一点:

struct foo *foo = alloca(256 + sizeof(struct foo));
foo->len = 256;
Run Code Online (Sandbox Code Playgroud)

从那里,我可以定义一个像这样的宏:

#define STACK_ALLOC_FOO(SIZE) ({                          \
    struct foo *_tmp = alloca(SIZE + sizeof(struct foo)); \
    _tmp->len = SIZE;                                     \
    _tmp;                                                 \
})
Run Code Online (Sandbox Code Playgroud)

并声明它:

struct foo *foo = STACK_ALLOC_FOO(256);
Run Code Online (Sandbox Code Playgroud)

但是,我不确定分配的内存的生命周期alloca()。是内部作用域还是函数?

另外,分配全局变量不起作用(即使这不是我主要关心的问题)。

有人有在堆栈上分配具有灵活数组成员的结构的良好实践吗?

c flexible-array-member

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

使用灵活的数组成员分配struct

这是C99代码:

typedef struct expr_t
{
    int n_children; 
    foo data; // Maybe whatever type with unknown alignment
    struct expr_t *children[];
} expr_t;
Run Code Online (Sandbox Code Playgroud)

现在,我该如何分配内存?

expr_t *e = malloc (sizeof (expr_t) + n * sizeof (expr_t *));
Run Code Online (Sandbox Code Playgroud)

要么

expr_t *e = malloc (offsetof (expr_t, children) + n * sizeof (expr_t *));
Run Code Online (Sandbox Code Playgroud)

sizeof甚至保证与柔性阵列构件的工作类型(GCC接受它)?

c c99 flexible-array-member

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

灵活阵列成员的真正好处是什么?

在阅读了一些与柔性阵列成员相关的帖子后,我仍然不完全理解为什么我们需要这样的功能.

可能重复:
C中的灵活数组成员 - 不好?
这是C中的Flexible Array Struct成员吗?

(如果我没有从上面可能的重复问题中解决我的问题,请怪我)

以下两个实现之间的真正区别是什么:

struct h1 {
    size_t len;
    unsigned char *data;
};

struct h2 {
    size_t len;
    unsigned char data[];
};
Run Code Online (Sandbox Code Playgroud)

我知道h2的大小就好像省略了灵活的数组成员(数据),即sizeof(h2) == sizeof(size_t).而且我也知道灵活的数组成员只能作为结构的最后一个元素出现,因此原始实现在位置上可以更灵活data.

我真正的问题是为什么C99添加此功能?仅仅因为sizeof(h2)不包含实际大小的数据?我相信我必须错过这个功能的一些更重要的观点.请指出给我.

c struct flexible-array-member

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

在使用灵活数组的结构初始化中使用sizeof运算符

我想在其中声明一个带有灵活数组成员的结构,然后使用sizeof()它.原型是:

typedef struct
{
    uint16_t    length;
    uint8_t     array[][2];
} FLEXIBLE_t;
Run Code Online (Sandbox Code Playgroud)

然后我宣布它:

const FLEXIBLE_t test = {
    .length = sizeof(test),
    .array = {  {   0,  1   },
                {   2,  3   },
                {   4,  5   },
                {   6,  7   },
                {   8,  9   } }
};
Run Code Online (Sandbox Code Playgroud)

一切编译好的(GCC),但是当我审视test.length它的值是2,也就是说,它只是计数uint16_tlength本身.

如何在编译时计算结构的大小?似乎编译器使用原型而不是特定实例.

c arrays struct sizeof flexible-array-member

7
推荐指数
3
解决办法
1176
查看次数

C99:联盟内的灵活阵列?

我试图将使用struct hack转换为使用灵活的数组成员,只是遇到以下错误消息:

错误:使用灵活数组成员的结构无效

(GCC 4.8.1,gnu99,MinGW)

在尝试追踪消息的原因之后,我将其提炼到以下相对最小的情况:

struct a {
    union {
        struct {
            int b;
            int c[];
        } d;
    } e;
};
Run Code Online (Sandbox Code Playgroud)

换句话说,具有灵活数组成员的结构看不到能够放入结构中的并集内,即使联合是结构的最后一个成员.

(请注意,将一个灵活的数组成员直接放在联合内部似乎确实有效.)

现在:除了恢复结构黑客(将c声明为长度为1的数组)之外,还有什么方法可以解决这个问题吗?指向联合内部结构的指针可以工作,但是会遇到额外的间接层.

c struct c99 flexible-array-member gnu99

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

具有灵活数组成员的结构的大小

特定

struct Foo {
    uint32_t a;
    uint32_t b[];
};
Run Code Online (Sandbox Code Playgroud)

什么是sizeof(Foo)?它是实现定义的还是未定义的行为?C vs C++的答案有何不同?

c c++ sizeof flexible-array-member

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