Is it possible to have a std::vector of struct with a fexible array member?
我有一个具有灵活数组成员的结构,需要使用它。
1 2 3 4 5 | struct Record { uint32_t length; Data contents[]; }; |
我可以初始化它并通过这样的方式使用它:(它还可以与malloc或任何其他动态分配一起使用)
1 2 3 4 5 6 7 | vector<Data> members; vector<uint8_t> buffer; Record myRecord; buffer.resize(sizeof(Record) + members.size() * sizeof(Data)); myRecord = *(reinterpret_cast<Record*>(buffer.data()); myRecord.length = static_cast<uint32_t>(members.size()); // copy members to myRecord.contents |
那就行了。但现在我需要有一个对成批记录进行操作的接口,我一直在尝试使用std::vector来实现这一点。然后问题开始出现,我猜这是因为std::vector在内存上连续排列所有元素,而且由于size of(record)不会考虑内容的大小(每个矢量元素只容纳4个字节,而不是4个字节+内容的大小*sizeof(data)),矢量元素实际上共享内存,然后每个元素开始覆盖上一个元素的内容。这有道理吗?
如果这确实是问题所在,我想知道是否有任何方法可以"强制"向量为每个元素分配一个特定的大小(而不是元素类型返回的size of)。这样我就可以确保每个向量元素都有足够的大小。如果不可能的话,还有其他的解决方案吗?也许另一个容器可以让我这样做?请记住,我确实需要使用它定义的结构(我希望只替换一个向量的整个内容,但不幸的是这是不可能的)
你的主要问题是:
1 | myRecord = *(reinterpret_cast<Record*>(buffer.data()); |
这只是覆盖堆栈变量中的数据。这并没有改变
你几乎可以肯定的是:
1 | Record *myRecord = (reinterpret_cast<Record*>(buffer.data()); |
然后将有一个指向由
不能将EDOCX1[5]视为值类型。就C++的对象模型而言,它不是一个值类型。它不能像大多数C++类型那样被复制或移动。只能通过指向此处使用的特定分配的指针/引用来操作它。
也就是说,像这样使用
1 | std::unique_ptr<char[]> storage = new char[sizeof(Record) + (members.size() * sizeof(Data))]; |
这也会阻止系统初始化内存,因为您无论如何都要覆盖它。
I was wondering if there's any way to"force" the vector to allocate a specific size for each element (instead of whatever sizeof returns for the element's type).
不,