std::realloc
在C++中存在风险,如果malloc的内存包含非pod类型。唯一的问题似乎是,如果无法原地扩展内存,std::realloc
将不会调用类型解构函数。
一个微不足道的解决方法是一个try_realloc
函数。如果无法在原地增长,则它不会malloc新内存,只需返回false。在这种情况下,可以分配新内存,将对象复制(或移动)到新内存,最后释放旧内存。
这似乎非常有用。std::vector
可能会大量使用它,可能避免所有复制/重新分配。
预先防护性灭火器:技术上而言,这与Big-O性能相同,但如果向量增长是应用程序的瓶颈,则即使Big-O保持不变,x2加速也很好。
但是,我找不到任何类似于try_realloc
的c api。
我错过了什么吗?try_realloc
不像我想象的那么有用吗?是否存在某些隐藏的bug使try_realloc
无法使用?
更好的是,是否存在一些不太记录的API可以像try_realloc
一样执行?
注意:很明显,我在特定于库/平台的代码中。我不担心try_realloc
本质上是一种优化。
更新:根据Steve Jessops对于vector是否更高效地使用realloc的评论,我编写了一个概念验证来测试。 realloc-vector
模拟了向量的增长模式,但具有realloc选项。 我将程序运行到向量的一百万个元素。
为了比较,vector
在增长到一百万个元素时必须分配19次。
如果 realloc-vector
是唯一使用堆的东西,结果非常棒,只需3-4次分配就能将大小增长到百万字节。
如果 realloc-vector
与一个以66%的速度增长的 vector
同时使用,则结果不那么可靠,在增长过程中需要进行8-10次分配。
最后,如果 realloc-vector
与以相同速度增长的 vector
同时使用,则 realloc-vector
需要进行17-18次分配。与标准向量行为相比,仅节省一个分配的效果微乎其微。
我不怀疑黑客可以通过游戏化分配大小来提高节省效果,但我同意 Steve 的看法,编写和维护这样的分配器所需的巨大努力并不值得回报。
vector
所持有的对象的复制性能很差,而且由于某种原因你不能使用deque
,那么也许你应该将你的vector
改为持有指向对象的shared_ptr
实例。这样复制操作就会变得更加便宜。我不确定unique_ptr
对象是否可以用于标准容器,但这样做甚至可以进一步减少复制开销。 - Praetorian