假设我有这段代码:
const struct
{
const char * const name;
const unsigned length;
const char data[951357];
} var[] =
{
{
"dataset1",
#include "dataset1.h"
},
{
"dataset2",
#include "dataset2.h"
},
/* ... */
};
每个dataset*.h
都包含以下内容:
6,
{
0x04, 0x08, 0x15, 0x16, 0x23, 0x42
}
这要求我事先知道最大数据集的大小。这不是面向未来的,因为任何添加数据集的人都必须检查并修改data
的大小,并且可能导致严重的内存浪费(在我的实际情况中,已经有~15个数据集,大小不等,数百KB)。
有什么方法吗?
唯一的硬性要求是每个数据必须位于自己的文件中,但该文件的格式可以是任何格式。我还希望将所有内容保留为const
。
编辑:我应该提一下旧代码是这样做的:
struct dataset { char* name; int length; char* data; };
struct dataset *alldata[10];
struct dataset dataset1 = {
"dataset1",
#include "dataset1.h"
};
/* same again for every dataset */
int main()
{
alldata[0] = malloc(sizeof(struct dataset));
memcpy(alldata[0], dataset1, sizeof(struct dataset));
/* again, block copied for each dataset */
}
这段代码对我来说很难看,并且需要(我认为)不必要的mem副本。我重写代码的目的是让它在编译时存储所有数据,然后在运行时只在必要时读取它。
答案 0 :(得分:1)
您可以使用指向数据的指针。你为额外的指针付出代价,但考虑到数据的大小,你可以节省很多,因为没有太大的数组。
#include "dataset1.h"
/* other dataset includes here */
struct DataSet {
const char * name;
unsigned length;
const char * data;
};
const struct DataSet var[] = {
{
"dataset1",
dataset1_length,
dataset1_data,
},
/* other dataset inits here */
};
<强> dataset1.h 强>
enum { dataset1_length = 6 };
extern const char dataset1_data[];
<强> dataset1.c 强>
const char dataset1_data[] = { 0x04, 0x08, 0x15, 0x16, 0x23, 0x42 };
请注意我删除了不必要的const
,但所有数据仍为const
。
如果不需要额外的编译单元,只需将标题和源文件合并到一个标题中并直接包含:
<强> dataset1.h 强>
enum { dataset1_length = 6 };
const char dataset1_data[] = { 0x04, 0x08, 0x15, 0x16, 0x23, 0x42 };
答案 1 :(得分:1)
您想要创建一个结构数组。数组要求每个元素的大小相同。说由于灵活的数组,你不能使用不同大小的结构创建任何数组,除非你修改数组成员的大小(正如你所做的那样)。
无论如何都有一个解决方案。使用指针更改可变长度数组成员,并在其他位置创建可变长度数组
我将解释的解决方案让您继续使用数组访问方法,因此您无需更改其余软件,只需对头文件进行少量修改。
主要结构声明将是:
const struct
{
const char const * name;
const unsigned length;
const char const *data; //This is the only difference
} var[] =
{
{
"dataset1",
#include "dataset1.h"
},
{
"dataset2",
#include "dataset2.h"
},
/* ... */
};
标题文件将按照以下方式制作:
6,
(const char const *)&(const char[]) {0x04, 0x08, 0x15, 0x16, 0x23, 0x42}
这里,(const char[]){0x04, 0x08, 0x15, 0x16, 0x23, 0x42}
部分在内存中创建了一个可变长度的char
常量数组。然后使用运算符&
获取其地址并将其转换为char指针,然后再将其分配给结构
在C99-C11下测试