存储和回收堆分配的可变大小对象,没有malloc和free

时间:2014-06-06 11:24:45

标签: c++ memory c++11 memory-management malloc

我想存储具有可变大小的多态对象,这些对象派生自免费商店中的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大小的对齐存储空间。

我已尝试在one of my previous questions中使用offsetofreinterpret_cast,但程序始终崩溃,我无法调试错误。

因此,我尝试使用std::mallocstd::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);
    }
};

以上代码似乎在我的程序中正常运行。

我要问的是:我怎样才能转换&#34;上面的C风格代码到现代C ++ 11 / C ++ 14代码,还要注意对齐吗?

1 个答案:

答案 0 :(得分:1)

似乎创建一个类似下面的类来完成这项工作:

template <typename T>
struct ClassWithBool
{
    bool b;
    T t;
};

然后您可以使用std::allocator来分配/销毁对象。