在内存管理器中分配数组

时间:2013-06-11 15:04:29

标签: c++ arrays pointers memory-management heap-memory

我想在内存管理器中成功分配一个数组。我很难在Heap中成功完成数据设置。我不知道如何实例化数组的元素,然后设置传入该数组的指针。 非常感谢任何帮助。 =)

基本上总结一下,我想使用自己的Heap块而不是普通的堆来编写自己的新[#]函数。甚至不想考虑动态阵列需要什么。的 o.O

// Parameter 1: Pointer that you want to pointer to the Array.
// Parameter 2: Amount of Array Elements requested.
// Return: true if Allocation was successful, false if it failed.
template <typename T>
bool AllocateArray(T*& data, unsigned int count)
{
    if((m_Heap.m_Pool == nullptr) || count <= 0)
        return false;

    unsigned int allocSize = sizeof(T)*count;
    // If we have an array, pad an extra 16 bytes so that it will start the data on a 16 byte boundary and have room to store
    // the number of items allocated within this pad space, and the size of the original data type so in a delete call we can move
    // the pointer by the appropriate size and call a destructor(potentially a base class destructor) on each element in the array
    allocSize += 16;

    unsigned int* mem = (unsigned int*)(m_Heap.Allocate(allocSize));
    if(!mem)
    {
        return false;
    }

    mem[2] = count;
    mem[3] = sizeof(T);

    T* iter = (T*)(&(mem[4]));
    data = iter;
    iter++;

    for(unsigned int i = 0; i < count; ++i,++iter)
    {
        // I have tried a bunch of stuff, not sure what to do.  :(
    }

    return true;
}

堆分配功能:

void* Heap::Allocate(unsigned int allocSize)
{
Header* HeadPtr = FindBlock(allocSize);
Footer* FootPtr = (Footer*)HeadPtr;
FootPtr = (Footer*)((char*)FootPtr + (HeadPtr->size + sizeof(Header)));

// Right Split Free Memory if there is enough to make another block.
if((HeadPtr->size - allocSize) >= MINBLOCKSIZE)
{           
    // Create the Header for the Allocated Block and Update it's Footer
    Header* NewHead = (Header*)FootPtr;
    NewHead = (Header*)((char*)NewHead - (allocSize + sizeof(Header)));
    NewHead->size = allocSize;
    NewHead->next = NewHead;
    NewHead->prev = NewHead;
    FootPtr->size = NewHead->size;

    // Create the Footer for the remaining Free Block and update it's size
    Footer* NewFoot = (Footer*)NewHead;
    NewFoot = (Footer*)((char*)NewFoot - sizeof(Footer));
    HeadPtr->size -= (allocSize + HEADANDFOOTSIZE);
    NewFoot->size = HeadPtr->size;

    // Turn new Header and Old Footer High Bits On
    (NewHead->size |= (1 << 31)); 
    (FootPtr->size |= (1 << 31));

    // Return actual allocated memory's location
    void* MemAddress = NewHead;
    MemAddress = ((char*)MemAddress + sizeof(Header));

    m_PoolSizeTotal = HeadPtr->size;
    return MemAddress;
}
else
{
    // Updating descriptors
    HeadPtr->prev->next = HeadPtr->next;
    HeadPtr->next->prev = HeadPtr->prev;
    HeadPtr->next = NULL;
    HeadPtr->prev = NULL;

    // Turning Header and Footer High Bits On
    (HeadPtr->size |= (1 << 31)); 
    (FootPtr->size |= (1 << 31));

    // Return actual allocated memory's location
    void* MemAddress = HeadPtr;
    MemAddress = ((char*)MemAddress + sizeof(Header));

    m_PoolSizeTotal = HeadPtr->size;
    return MemAddress;
}
}

Main.cpp的

int* TestArray;

MemoryManager::GetInstance()->CreateHeap(1);  // Allocates 1MB

MemoryManager::GetInstance()->AllocateArray(TestArray, 3);

MemoryManager::GetInstance()->DeallocateArray(TestArray);

MemoryManager::GetInstance()->DestroyHeap();

1 个答案:

答案 0 :(得分:0)

至于这两个具体要点:

  1. 实例化数组的元素
  2. 设置传入该数组的指针。
  3. 对于(1):在C ++中没有“初始化”数组元素的明确概念。至少有两种合理的行为,这取决于你想要的语义。第一种是简单地将数组归零(参见memset)。另一种方法是为数组的每个元素调用默认构造函数 - 我不建议使用此选项,因为默认(零参数)构造函数可能不存在。

    编辑:使用inplace-new初始化的示例

     for (i = 0; i < len; i++)
        new (&arr[i]) T();
    

    For(2):“你的意思并不完全清楚”,然后设置传入该数组的指针。您可以“设置”返回的内存为data = static_cast<T*>(&mem[4]),您已经这样做了。

    其他一些警告(编写自己的内存管理器),要非常小心字节对齐(reinterpret_cast(mem)%16);你需要确保你返回的是单词(甚至是16字节)对齐的点。另外,我建议使用inttypes.h明确使用uint64_t来明确大小 - 当前看起来这个分配器会因> 4GB分配而中断。

    编辑: 从实验说起 - 编写内存分配器是一件非常困难的事情,调试起来更加痛苦。正如评论者所说,内存分配器是特定于内核的 - 因此有关您的平台的信息将非常有用。