1

如果我有一个容器:

std::vector<T*> elements;

我可以使用placement new 来分配我的对象,以便所有对象都连续分配吗?这样我就可以做这样的事情:

size_t elementIndex = someRandomElement - elements[0];

someRandomeElement随机元素来自哪里elements,然后elementIndex将存储正确的索引,someRandomElement以便elements[elementIndex] == someRandomElement

这是我当前实现内存管理器所必需的。我有一个我今天能够完成的实现,但它要求元素(可以是体素、三角形或其他任何东西)具有 GetIndex() 和 SetIndex() 函数,以便当元素作为指针返回时,我可以找到elements数组中元素的索引,这意味着我无法更改的任何元素(比如说 Ogre::Vector3)都无法使用管理器(在我的情况下,我需要它们使用它,因为它们正在碎片化记忆)。

我唯一的其他解决方案是拥有一个充当访问器并具有索引以及指向元素的指针的结构,尽管这会导致内存使用量增加(考虑到我现在正在处理 500 万个元素)。

注意:我今天发布了一个类似的问题,但那里的答案做出了一些完全违背我的要求的假设。其中一项要求是向量必须填充指向T否则大部分代码库需要更改的指针。其次,初始化超过 100,000 个(大约)元素会导致 bad_alloc 异常。每个元素的大小为 196 字节(我已设法将其减少到 132 字节)。

4

2 回答 2

2

为了使您的指向对象连续,您有两个合理的选择:

  • 用于new[]创建一个足够大的元素数组以容纳所有元素,然后为它们分配新值并将它们的地址放入元素中
  • 使用 malloc() 创建一个足够大的未初始化内存区域来保存它们(它可能会足够严格地对齐,但您应该意识到这个问题),然后使用放置new在该内存中构造您的元素

不要使用new[]then placement new,因为默认构造的元素在放置 new 覆盖他们的内存之前不会被破坏......因此他们的构造函数占用的任何资源、它维护的计数器等都不能被析构函数正确释放/更新。

如果你没有足够的内存来分配大数组,那么显然你不能这样做......就这么简单。预计100,000 个单独new T的 s 需要比单个更多的内存new T[100000]......但是与分配相关的填充和堆管理开销。

于 2011-04-22T03:10:12.590 回答
1

std::bad_alloc异常可能是因为您试图分配太大的连续内存块。因此,请考虑使用 astd::deque<T>代替。

如果您决定std::vector<T*>出于某种原因仍然需要 a,则可以将指向元素的指针存储在std::deque<T>. 只要您只从序列的开头或结尾添加和删除元素,您就不必担心指针会失效。

于 2011-04-22T03:15:38.893 回答