使用 std::vector<char> 作为异构记录的存储是否安全?

Is it safe to use std::vector<char> as storage for heterogeneous records?

本文关键字:记录 存储 异构 是否 安全 gt vector std lt char 使用      更新时间:2023-10-16

我需要处理由一系列 POD 元素组成的记录。 在处理一系列这些记录之前,会在运行时找到这些元素的类型。理想情况下,记录的存储将连续保存元素,以便可以直接填充存储或使用系统 IO 调用输出存储。

给定以下简化的示例代码:

template<typename T>
struct ElementAccessor {
ElementAccessor(int offset)
:
_offset(offset)
{}
T &operator () (void * data)
{
return reinterpret_cast<T &>(
*reinterpret_cast<char *>(data) + _offset);
}
int _offset;
};
ElementAccessor<float> fEl(0);
ElementAccessor<int> iEl(sizeof(float));

我正在寻找一种有效且方便的方法来存储记录?

我考虑了以下方法:

vector<int>

使用vector<int>似乎很方便:

std::vector<int> intData(2);
iEl(intData.data()) = 42;
fEl(intData.data()) = 12.4f; //< Uh-oh,  undefined behaviour, maybe zero initialization could be reordered after this point!

但会违反严格别名规则。

Raw allocated memory

我相信以下是有效的代码,但由于内存管理是手动的,因此不方便:

void *voidData(operator new(2 * sizeof(int)));
iEl(voidData) = 42;
fEl(voidData) = 12.4f;
...
operator delete(voidData);

std::vector<char>

如何使用std::vector<char>

std::vector<char> charData(2 * sizeof(int));
iEl(charData.data()) = 42;
fEl(charData.data()) = 12.4f; 

这很方便,因为std::vector很好地处理了内存管理。 但它有效吗?

根据标准,您提出的选项都不正确,因为违反了严格别名和对齐。

您可以做的是在缓冲区的任意偏移量和您选择的类型之间memcpy。 但没有对"就地"的数据进行操作。