我一直在做一个小项目来了解动态内存分配的工作原理。我有一个用作堆的全局字符缓冲区。看完these lecture notes我已经为内存管理编写了 Alloc、DeAlloc、MergeBlocks 和 SplitBlocks 函数。 Alloc 和 DeAlloc 的功能类似于 malloc 和 free,但它们写入我的堆数组。现在我已经让它们工作了,我想知道如何重载一个简单的类以利用我的内存管理。
// Memory Block structure
// -------------------------------
// | size | active | 2 bytes
// -------------------------------
// | | n bytes
// | payload |
// | |
// -------------------------------
// | padding | m bytes (n + m + 4 is a multiple of 8)
// -------------------------------
// | size | active | 2 bytes
// -------------------------------
unsigned char heap[2064]; // fake heap
// -----------------------------------------------------------------------
// Omitting a bunch of memory management functions that manage the heap
// -----------------------------------------------------------------------
struct SimpleStruct
{
unsigned short x;
SimpleStruct(unsigned short x)
{
this->x = x;
}
// Need to override -> operator but not sure what to do
void* operator new(size_t size)
{
return (void*)Alloc(size);
}
};
int main()
{
SimpleStruct* s = new SimpleStruct(5);
s->x = 3;
}
我觉得我需要做几件事:
首先我需要将成员变量值实际存储在我的自定义堆上
其次,我需要让 ->() 运算符在堆中的适当位置查找成员变量。我可以在构造函数中执行此操作,但如果不使用 new,我希望将它们存储在堆栈中
我试过在线查找信息,但似乎找不到任何线索。我什至不确定这是可能的。任何帮助将不胜感激
最佳答案
您的对象将在 operator new
返回的地址处构建。如果 Alloc
返回的地址指向 block 的元数据,则 operator new
需要将该指针调整为该对象不会覆盖元数据:
void* operator new(size_t size)
{
char* block = (char*)Alloc(size);
return (void*)(block + 2);
}
然后您将需要一个匹配的operator delete
,它可以找到给定有效负载指针的元数据:
void operator delete(void* ptr)
{
char* block = (char*)ptr - 2;
DeAlloc(block);
}
将这些调整直接放入 Alloc
和 DeAlloc
可能是个好主意,以防止可能的错误破坏堆。这正是许多 malloc
和 free
实现所做的,所以这是分配函数的预期行为,它可以防止用户需要知道堆的内部结构才能使用
关于c++ - 覆盖新的和成员访问运算符以使用自定义堆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48968842/