2016-07-30 15 views
2

我想重写操作new有这样的签名:new操作符返回更多的内存比要求

void* operator new(size_t bytes, MemoryManager* man); 

和类MemoryManager看起来是这样的:

struct MemoryManager 
{ 
    virtual void* Allocate(size_t bytes) = 0; 
    virtual void Deallocate(void* ptr) = 0; 
}; 

现在我想做的事重载的new函数分配的内存比要求的要多。然后在最后几个字节中它将存储一个指向MemoryManager对象的指针,以便它知道在我的自定义delete运算符中使用了什么函数。所以它看起来像这样分配:

__________ 
|   | _ 
|__________| | 
|   | | 
|__________| | 
|   | | <---- Bytes requested for object 
|__________| | 
|   | | 
|__________| | 
|   | _| 
|__________| 
|   | _ 
|__________| | <---- Pointer to MemoryManager 
|   | _| 
|__________| 

现在我真正的问题是:这样做会导致未定义的行为?有些事情可能是一个问题:

  • 这可能是不确定的new返回多个字节比请求
  • 您可能会遇到对齐问题(但这些也许可以克服)
+5

我不知道任何禁止'new char [10]'返回100兆内存的东西。当然,这样的东西不会很有用。但是,C++中没有任何东西禁止它,AFAIK。 –

+3

传统上你通过在对象之前存储额外的数据*来做到这一点,因为在销毁时你没有给出大小。这是一种常见的技术。分配X个额外的字节,在第一个X字节中写入内容,然后将X字节返回到缓冲区。 – Yakk

回答

9

这这种事情相当普遍。但是,您通常会在开始时而不是结束时存储额外的数据(关注平台的最大对齐方式,即您可能需要填充)。语言中没有任何内容禁止你提出的建议。

4

从[basic.stc.dynamic.allocation]:

分配函数尝试分配存储的所请求的量。如果成功的话,它应该返回一个存储块的开始地址,其字节长度应该是,至少与请求的大小一样大。

强调增加。所以是的,这个标准允许一个有效的存储区域拥有比严格要求的更多空间。