存储和回收没有malloc和free的堆分配的可变大小对象
Storing and recycling heap-allocated variable size objects without malloc and free
我想存储可变大小的多态对象,这些对象来自自由存储上的Base
类。
我还想在同一个内存块中存储一个bool
值,就在为派生对象保留的内存之前。
/*
Desired memory layout for storage of one object:
base address
v
| | |
| bool | . . . . . variable size . . . . . |
| | |
^ ^
object address end address
*/
我尝试的第一件事是创建一个struct
与bool
成员和一个模板传递参数std::size_t
大小的对齐存储。
我试过使用offsetof
和reinterpret_cast
,就像我以前的一个问题一样,但程序总是崩溃,我无法调试错误。
因此,我尝试使用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++ 将抽象类型的动态分配对象传递给函数并存储在向量中
- 堆分配对象中的堆栈对象在 c++ 中在哪里分配?
- 在 c++ 的构造函数中分配对象向量时出错
- 动态分配对象中的字段-动态分配更好还是静态分配更好?C++
- 操作后通过运算符分配对象
- 如何捕获源自静态分配对象的构造函数的异常?
- 在C++中,当重新分配对象时,为什么构造函数在析构函数之前触发?
- 如何使用每个对象的单个构造函数参数动态分配C++对象数组?
- 将动态分配对象传递到 boost::any 构造函数中
- 混合指向已分配对象和作用域对象的指针
- C 删除指向动态分配对象的指针
- 有关动态分配对象的问题
- 类的堆分配对象是否在其作用域之后但在 C++ 中调用其析构函数之前处于活动状态
- C++ 中的黑白堆分配对象和堆栈分配对象的性能差异
- 是隐式创建的默认构造函数,负责分配对象内存
- 如何删除用于动态分配对象的智能指针
- 分配对象数组时如何初始化每个对象
- 用于堆栈分配对象的C++虚拟析构函数内联