我想在自由存储上存储从 Base
类派生的可变大小的多态对象。
我还想在同一个内存块中存储一个 bool
值,就在为派生对象保留的内存之前。
/*
Desired memory layout for storage of one object:
base address
v
| | |
| bool | . . . . . variable size . . . . . |
| | |
^ ^
object address end address
*/
我尝试的第一件事是创建一个带有 bool
成员和模板传递参数 std::size_t
对齐存储的 struct
> 尺寸。
我试过使用 offsetof
和 reinterpret_cast
就像在 one of my previous questions 中一样, 但程序总是崩溃,我无法调试错误。
因此,我尝试使用 std::malloc
和 std::free
,程序按预期运行。
但是,我现在缺少 C++ new
/delete
安全性,而且我没有任何对齐方式。
我真的很想找到一种方法来使用 std::aligned_storage
或确保代码可以在任何平台上运行并且符合标准的东西来重新实现下面的代码。
我想在内存中存储实际对象之前的附加 bool
。
struct Base { virtual ~Base() { } };
struct Der1 : Base { char c[100]; };
struct Der2 : Base { char c[200]; };
template<typename TBase> struct LocalRecycler
{
// Allocated, but unused pointers, that can be recycled
std::vector<void*> recyclable;
// Upon destruction, free all allocated memory
// No need to call the destructors, as I'm 100% sure recyclable
// pointers alredy destroyed their inner object
~LocalRecycler()
{
for(auto p : recyclable) free(p);
}
// I'm omitting variadic template parameters for generic construction,
// as they are not relevant to the question
template<typename T> T* create()
{
void* objAddress;
// If we have some space that is already allocated, use it
// Otherwise, allocate new space
if(!recyclable.empty())
{
objAddress = recyclable.back();
recyclable.pop_back();
}
else
{
// Note how I'm not taking into account alignment here
// That's one reason why I would like to avoid using `std::malloc`
objAddress = std::malloc(sizeof(bool) + sizeof(T));
}
// Construct a `bool` at the beginning of the allocated memory block
// Construct a `T' after the bool
new (objAddress + 0) bool{true};
new (objAddress + sizeof(bool)) T{};
return reinterpret_cast<T*>(objAddress + sizeof(bool));
}
void recycle(void* mPtr)
{
// Destroy the inner object
TBase* basePtr{reinterpret_cast<TBase*>(mPtr + sizeof(bool))};
basePtr->TBase::~TBase();
// The memory block can now be reused
recyclable.emplace_back(mPtr);
}
};
上面的代码似乎在我的程序中运行正常。
我要问的是:如何将上述 C 风格代码“转换”为现代 C++11/C++14 代码,同时还要注意对齐?
最佳答案
似乎创建一个像下面这样的类就可以完成这项工作:
template <typename T>
struct ClassWithBool
{
bool b;
T t;
};
然后您可以使用 std::allocator
来分配/销毁对象。
关于c++ - 在没有 malloc 和 free 的情况下存储和回收堆分配的可变大小对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24080690/