首页 > 解决方案 > 结构中带有空索引的数组有什么用?

问题描述

我在此处的结构定义中的索引中看到了一个未提及大小的数组。然后我尝试对示例代码重复相同的操作

struct some {
char a[];
};

它抛出一个错误:flexible array member in otherwise empty struct

所以我尝试添加另一个成员

struct some {
unsigned int x;
char a[];
};

并且编译成功;我所做的观察是sizeof(struct some)= sizeof(unsigned int)。这意味着,a不会在内存中获得任何份额。


,而且,在初始化数组时最后使用逗号有什么用吗?

struct other array[] = {
  {....},
  {....},
};

标签: arrayscstructlinux-kernel

解决方案


对于第一个问题:灵活数组对于减少内存分配很有用(而不是分配一个结构和一个缓冲区,你只分配一个结构)。

一个例子可能会让事情更容易理解。

让我们想象以下场景:我们有一个自定义文件格式,其中前 32 位整数表示大小N,接下来的N字节是我们感兴趣的一些有效负载,所以:

4 // the next 4 bytes are some data we need to parse
1 2 3 4
8 // the next 8 bytes represent another chunk of data
1 2 3 5 6 7 8

这可以用以下结构表示:

struct file_chunk {
    int count;
    char *data;
}

我们不知道一个文件会有多少块,所以对于每个块我们必须做两次分配:一个用于file_chunk结构,另一个用于data缓冲区:

file_chunk *allocate_file_chunk(int Count) {
    struct file_chunk *chunk = malloc(sizeof(*chunk));
    chunk->data = malloc(Count);
    return chunk;
}

但是我们知道我们总是有一个 32 位整数N后跟N字节,所以我们可以执行以下操作:

struct file_chunk {
    int count;
    char data[]
}

file_chunk *allocate_file_chunk(int Count) {
    return malloc(sizeof(struct file_chunk) + Count * sizeof(char));
}

现在我们的结构看起来与我们从文件中读取的部分完全一样。

该功能是在 C99 中引入的。或者,您可能会看到1为不支持灵活数组成员的编译器定义了一个大小数组的结构:

struct file_chunk {
    int count;
    char data[1]
}

这使得计算分配所需的大小稍微复杂一些:

size_t file_chunk_size = sizeof(struct file_chunk) + Count * sizeof(char) - sizeof(char);

至于第二个问题:你可以省略结尾的,. 它只是使最后添加新条目更容易(并减少查看差异时更改的行)。


推荐阅读