我想在另一个分配器(通常在内部调用 realloc)返回的内存中构造任意 C++ 对象。我知道通常可以将新的内容放入 malloc 内存中。但是,我希望所有 C++ 对象在连续分配的内存中之前都有另一个公共(public)对象。该 header 对象将包含有关以下 C++ 对象的信息。从对齐的角度来看,我不知道分配 (sizeof(header) + sizeof(type)) 内存然后在 (mem + sizeof(header)) 构造类型是否安全。我认为这并不是因为 (mem + sizeof(header)) 不能保证类型正确对齐。
我考虑过各种可能性,例如生成一个模板类型,声明 header 后跟类型 T 并分配 sizeof(ObjPlusHeader<T>)
。然而,问题是该结构将作为 void* 显示在我的代码的另一部分中(由我无法控制的外部库强制),所以我必须知道将其转换为什么。我想转换到 Header* 而不是 ObjectPlusHeader<???>*
.
我知道使用标准布局类型,我可以将对象转换为指向其第一个成员的指针。但是,T 不一定是标准布局,在这种情况下 ObjectPlusHeader<T>
即使标题是,也不会是标准布局。我还考虑过让包装模板从 Header 公开派生,从 T 私有(private)派生,而不是包含 T。但是,如果不首先转换为存储的实际类型,将 void* 直接转换为 Header* 仍然是不合法的。我不会知道。
我想要的是由分配器分配的连续内存(本质上是重新分配),其中我知道 Header 位于开头,并且任意 C++ 对象位于我知道并可以存储的某个正确对齐的地址 >= mem + sizeof(Header) 处在标题中。因此,给定 void* 我可以将其转换为 Header* 并获取该对象。但是,我不确定潜在的对齐问题。
最佳答案
只需编写一个 (constexpr) 函数来计算适当的填充:
template<typename T>
size_t paddingAfterHeader() {
auto rem = sizeof(Header)%alignof(T);
return rem ? alignof(T) - rem : 0;
}
分配:
void *mem = malloc( sizeof( Header ) + paddingAfterHeader<T>() + sizeof(T) );
关于c++ - 如何使用 header 对象在 malloc 内存中安全地构造 C++ 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40409689/