如果我有一个容器:
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万个元素)
注意:我今天发布了一个similar question,但是那里的答案做出了一些完全违背我要求的假设。其中一个要求是向量必须填充指向
T
的指针,否则需要更改大部分代码库。其次,初始化超过100,000(大约)元素会导致bad_alloc异常。每个元素的大小为196个字节(我已设法将其减少到132个字节)。
答案 0 :(得分:2)
要使指向的对象连续,您有两个合理的选择:
new[]
创建一个足以容纳所有元素的元素数组,然后为其分配新值并将其地址放入元素中new
构建你的那个记忆中的元素不要使用new[]
然后使用new
,因为默认构造的元素在放置之前不会被破坏,因为它会占用内存...因此构造函数采用的任何资源,计数器维护等等。析构函数无法正确释放/更新。
如果你没有足够的内存来分配大数组,那么很明显你不能这样做......就这么简单。预计100,000个单独的new T
需要比单个new T[100000]
更多的内存,但是......存在与分配相关的填充和堆管理开销。
答案 1 :(得分:1)
std::bad_alloc
异常可能是因为您试图分配过大的连续内存块。因此,请考虑使用std::deque<T>
。
如果您因某种原因决定仍然需要std::vector<T*>
,则可以存储指向std::deque<T>
中元素的指针。只要您只添加和删除序列开头或结尾的元素,您就不必担心指针被无效。