jma*_*erx 8 c++ memory-management vector
我正在制作一个游戏,我有一个子弹飞来飞去.子弹完成后,我做bullets.erase(bullets.begin()+ i); 然后子弹消失了.然而,它似乎没有得到记忆棒.如果我创造了5000个子弹,那么在这些子弹消失之后再创建5,000个子弹,内存保持不变,但如果我创造5000多个,而这些5000个飞行,它将分配新的空间.我该怎么办才能真正释放这段记忆?
Tyl*_*nry 15
该std::vector级自动管理其内部存储器.它将扩展为容纳尽可能多的项目,但一般来说,当你删除项目时它不会自行缩小(尽管它会在它破坏时释放内存).
在std::vector有"大小"的两个相关的概念.首先是"保留"大小,它是从系统分配用于存储向量元素的内存量.第二个是"已使用"大小,即向量中逻辑上有多少元素.显然,保留的大小必须至少与使用的大小一样大.您可以使用该size()方法(我相信您已经知道)发现使用的大小,并且您可以使用该capacity()方法发现保留的大小.
通常,当使用的和保留的大小相同,并且您尝试插入新元素时,向量将分配一个两倍于先前保留大小的新内部缓冲区,并将所有现有元素复制到该缓冲区中.这对您来说是透明的,除了它将使您持有的任何迭代器无效.正如我之前提到的,AFAIK,大多数STL实现永远不会缩小保留大小作为对擦除的响应.
不幸的是,虽然您可以使用该方法强制向量增加其保留大小reserve(),但这不能用于减少保留容量.据我所知,实现减少容量的最佳选择是执行以下操作:
std::vector<Bullet>(myVector).swap(myVector);
Run Code Online (Sandbox Code Playgroud)
这将做的是创建一个临时向量,它是原始向量的副本(但具有最小必要容量),然后交换两个向量的内部缓冲区.这将导致您的原始矢量具有相同的数据,但可能更小的保留大小.
现在,因为创建该临时副本是一项相对昂贵的操作(即它比正常的读取/插入/删除需要更多的处理器时间),所以每次擦除元素时都不希望这样做.出于同样的原因,这就是为什么当你需要超过现有的大小时,向量会将其保留的大小加倍,而不是将其增加1.因此,我建议的是,在擦除相对大量的元素之后,并且您知道不会在短时间内添加更多元素,请执行上面的交换"技巧"以减少容量.
最后,您可能还想考虑使用除此之外的其他内容std::vector.从许多其他类型的数据结构中删除矢量中间的元素,这似乎是你经常做的,是一个缓慢的操作(因为向量必须将所有后续元素复制回一个插槽以填充空洞) .哪种数据结构最适合您的用途取决于您使用数据做了什么.