c - 分配连续内存以包含具有灵活数组成员的多个结构
问题描述
考虑一个包含灵活数组成员的结构,如下所示:
typedef struct {
size_t len;
char data[];
} Foo;
我有一个未知数量的 Foo,每个都是未知大小,但是我可以确定我所有的 Foo 加起来正好是 1024 字节。如何在知道每个 Foo 的长度之前为一个 Foos 数组分配 1024 个字节,然后再填充该数组的成员?
像这样的东西,虽然它抛出了一个段错误:
Foo *array = malloc(1024);
int array_size = 0;
Foo foo1;
strcpy(foo1.data, "bar");
array[0] = foo1;
array_size++;
Foo foo2;
strcpy(foo2.data, "bar");
array[1] = foo2;
array_size++;
for (int i = 0; i < array_size; i++)
puts(array[i].data);
想要这样做的原因是将所有 Foos 保持在一个连续的内存区域中,以便 CPU 缓存友好。
解决方案
你根本不能有一个 foos 数组,因为 foo 没有固定的大小,并且数组的定义特征是每个对象都有固定的大小和从其索引的基本可计算偏移量。对于您想要工作的内容,索引array[n]
必须知道foo[0]
, foo[1]
, ...,的完整大小foo[n-1]
,这是不可能的,因为语言不知道这些大小;在实践中,灵活的数组成员只是被排除在大小之外,因此将与's 的数据foo[1]
“重叠” 。foo[0]
如果您需要能够以数组的形式访问这些对象,则需要放弃在每个对象中放置一个灵活的数组成员。相反,您可以将所有数据放在最后,并在每个数据中存储指向数据的指针或偏移量。如果您不需要能够将它们作为数组访问,则可以改为在分配的内存中构建一种链表,将下一个条目的偏移量存储为每个条目的成员。(例如,参见如何struct dirent
在getdents
大多数 Unices 上使用。)
推荐阅读
- java - OnMouseRelease 的行为类似于 OnMouseClick
- amazon-web-services - AWS:如何从基于 Windows 的 EC2 机器推送事件查看器日志
- ios - 带有 WKWebView 单元格的滚动 UICollectionView 的 UITableView
- php - 在 Woocommerce 管理订单页面(运输部分)中用 SKU 替换产品名称
- python - 如何解决错误“object.__new__() 不带参数”?
- c# - 如何在 C# 上读取 .Key 文件?
- shell - 如何让 ffmpeg 在特定时间开始下载流?
- android - Android:将 LiveData 设置为 MutableLiveData
- r - 无法执行 updateR 命令
- postgresql - 如何参数化搜索 jsonb 数组包含?