【问题标题】:Create objects in pre-allocated memory在预分配内存中创建对象
【发布时间】:2012-01-08 05:15:27
【问题描述】:

我们可以使用placement new 在预分配的内存中创建一个对象。

让我们考虑以下示例:

char *buf  = new char[1000];   //pre-allocated buffer
string *p = new (buf) MyObject();  //placement new 
string *q = new (buf) MyObject();  //placement new

我在预分配的缓冲区中创建了两个对象。这两个对象是在缓冲区中随机创建的还是在连续的内存块中创建的?如果我们不断在缓冲区中创建更多对象并希望将它们存储在连续的内存块中,我们应该怎么做?先在缓冲区中创建一个数组,然后在数组的元素槽中创建每个对象?

【问题讨论】:

  • "如果我们不断在缓冲区中创建更多对象,并希望它们存储在连续的内存块中,我们应该怎么做?"使用std::vector,它是一个连续存储的动态数组。

标签: c++ arrays memory-management


【解决方案1】:

这两个对象都创建在同一个内存位置,即buf。这是未定义的行为(除非对象是 POD)。

如果要分配多个对象,则必须递增指针,例如buf + n * sizeof(MyObject),但要注意对齐问题

完成后不要忘记调用析构函数。

【讨论】:

  • 因为缓冲区是用new 分配的,所以它具有支持任何类型(包括数组)的对齐方式。 (一般来说,并不是你错了,只是在这种情况下他是安全的。)
  • @GMan:谢谢,好点子。如果您想将不同类型的对象放入内存中,我想需要额外注意。
  • “普通旧数据”,即基本类型,或 POD 数组,或没有构造函数的类等仅包含 POD。任何仅由其二进制表示形式确定并且可以被记忆复制的东西。
【解决方案2】:

以下代码行:

string *p = new(adr) MyObject();

将在地址 adr 创建一个 MyObject 对象。然后下次创建另一个对象时,您会知道 adr 处的内存正在被第一个对象使用,因此您的下一个对象必须在adr + sizeof(MyObject) 创建:

string *q = new(adr + sizeof(MyObject)) MyObject();

预分配内存的意义在于您不会在运行时分配内存,这非常慢。您在循环/程序开始时进行了一次大分配,然后您只需要使用该分配的块。不利的一面是您必须管理自己的内存,这意味着您必须弄清楚将对象放在哪里,当您的内存池变得碎片化时,这会变得很棘手!

【讨论】:

  • 如果 adr = static_cast(byteaddr) 那么你会这样做: string *q = new(adr+1)MyObject();
猜你喜欢
  • 2014-03-31
  • 2023-03-18
  • 1970-01-01
  • 2011-09-13
  • 2012-02-21
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 2015-10-15
相关资源
最近更新 更多