在矢量容器中使用新放置
Using placement new in a Vector Container
如果我有一个容器:
std::vector<T*> elements;
我是否可以使用放置新来分配我的对象,以便所有对象都连续分配?这样我就可以做这样的事情:
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 字节(。
要使指向的对象连续,您有两个合理的选择:
- 使用
new[]
创建一个足够大的元素数组来容纳所有元素,然后将新值分配给它们并将它们的地址放入元素中
使用 - malloc(( 创建一个足够大的未初始化内存区域来容纳它们(它可能足够严格对齐,但您应该意识到这个问题(,然后使用放置
new
在该内存中构造您的元素
不要使用 new[]
然后放置new
,因为在放置 new 覆盖它们的内存之前,默认构造的元素不会被破坏......因此,析构函数无法正确释放/更新其构造函数占用的任何资源、它维护的计数器等。
如果您没有足够的内存来分配大数组,那么显然您无法做到这一点......就这么简单。 不过,预计 100,000 个单独的new T
需要比单个new T[100000]
更多的内存......存在与分配关联的填充和堆管理开销。
std::bad_alloc
异常可能是因为您尝试分配的连续内存块太大。 因此,请考虑改用std::deque<T>
。
如果您出于某种原因决定仍需要std::vector<T*>
,则可以在std::deque<T>
中存储指向元素的指针。 只要只在序列的开头或结尾添加和删除元素,就不必担心指针失效。
- 使用新行和不使用新行读取文件
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 遇到新行时,有没有办法停止istream_iterator
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 计算缩放多边形的比例,得到给定的多边形面积
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- QwtPlot具有相等的轴和自动缩放
- 如何在directx/c++中进行平移/缩放操作
- 模板元编程:如何将参数包组合成新的参数包
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 我可以将新的 std::tuple 放入内存映射区域,并在以后读回吗?
- C++,打开和编辑文本文件中的数字数据,并将结果放入新文件中
- 将 int 放入 char 数组是否在法律上需要新的放置
- 如何将未排序数组的排序索引放入新数组中
- 视觉计数重复,并将唯一条目放入数组 [C++] 中的新数组中
- c++将行getline放入数组中,用新行分隔
- 读取文件夹中的所有文件,然后将每个文件及其匹配项放入新的excel文档中.是否可以用c++
- Visual Studio将新文件放入错误的目录中