1

我想在我的内存管理器中成功分配一个数组。我很难在我的堆中成功设置数据。我不知道如何实例化数组的元素,然后设置传递给该数组的指针。任何帮助将不胜感激。 =)

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

// 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;
}
}

主文件

int* TestArray;

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

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

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

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

1 回答 1

0

至于这两个具体点:

  1. 实例化数组的元素
  2. 设置传入该数组的指针。

对于 (1):在 C++ 中没有“初始化”数组元素的明确概念。至少有两种合理的行为,这取决于你想要的语义。第一个是简单地将数组归零(参见 memset)。另一种方法是为数组的每个元素调用默认构造函数——我不推荐这个选项,因为默认(零参数)构造函数可能不存在。

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

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

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

其他几句警告(我自己写过内存管理器),注意字节对齐(reinterpret_cast(mem) % 16);您需要确保返回的点是字(甚至 16 字节)对齐的。另外,我建议使用 inttypes.h 来明确地使用 uint64_t 来明确调整大小——目前看来,这个分配器会因 >4GB 分配而中断。

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

于 2013-06-11T17:21:48.017 回答