【发布时间】:2021-03-27 01:14:18
【问题描述】:
我目前正在实现我自己的矢量容器,我遇到了一个非常有趣的问题(至少对我来说)。这可能是一个愚蠢的问题,但我不知道。
我的向量使用一个堆指针数组来堆分配未知类型的对象 (T**)。 我这样做是因为我希望单个元素的指针和引用保持不变,即使在调整大小后也是如此。
这会在构造和复制时以性能为代价,因为我需要在堆上创建数组以及在堆上创建数组的每个对象。 (堆分配比栈上慢,对吧?)
T** arr = new *T[size]{nullptr};
然后对于每个元素
arr[i] = new T{data};
现在我想知道如果不是单独分配每个对象,我可以在堆上创建第二个数组并将每个对象的指针保存在第一个数组中,这是否安全、有益(更快)和可能。然后使用(并删除)这些对象,就好像它们是单独分配的一样。
=> 在堆上分配数组是否比单独分配每个对象更快?
=> 在数组中分配对象并稍后忘记数组是否安全? (我觉得听起来很愚蠢)
链接到我的 github 仓库:https://github.com/LinuxGameGeek/personal/tree/main/c%2B%2B/vector
感谢您的帮助:)
【问题讨论】:
-
“未知类型 T”是什么意思?你的意思是模板类型参数吗?
-
您想要实现的是对类似双端队列的容器使用放置新分配。这是一个可行的优化,但通常这样做是为了减少分配调用和内存碎片,例如在某些 RT 或嵌入式系统上。在这种情况下,该数组甚至可能是一个静态数组。但是,如果您还要求 T 的实例占据相邻空间,这是一个自相矛盾的要求,使用它们会扼杀任何性能提升。
-
请注意,如果您使用placement new,则不应在创建的对象上使用
delete,您必须直接调用析构函数。就delete而言,放置新重载不是真正的new。您可能会或可能不会导致错误,但如果您使用静态数组肯定会导致崩溃,并且在删除与动态分配的数组开头具有相同地址的元素时会导致堆损坏。 -
std::vector+ 内存池几乎是无与伦比的。只需使用它。 -
@nada 它没有为您提供对 OP 想要的元素的稳定引用。
标签: c++ arrays vector dynamic-memory-allocation heap-memory