繁体   English   中英

使用地图 <int, Foo> 代替矢量 <Foo> 避免指针失效

[英]Using map<int, Foo> instead of vector<Foo> to avoid pointer invalidation

假设我有一个Foo类和一个容器vector<Foo> Foos 我使用的算法在很大程度上依赖于指向Foos元素的指针,并且我还需要动态添加Foo并访问容器的元素。 问题是,如果我向向量添加太多元素,则可能需要重新分配元素,从而使指向这些元素的所有指针无效。 然后使用map<int, Foo>代替vector<Foo>有意义吗?

std::deque具有与vector类似的性能(和随机访问),但不会在插入时使指针无效。

但是,它确实会使删除指针无效。

我将使用std::vector<std::shared_ptr<Foo>> ,所以我仍然有一个向量,无论它们在向量中的位置如何,我仍然需要任何有效的指针。

这个答案集中于如何防止指针失效的发生,同时仍然坚持std::vector

预分配

如果事先知道向量可以包含的Foo对象的最大数量,则可以使用std::vector::reserve()成员函数简单地重新分配向量的缓冲区。 这样,就不会发生对象的重新分配,因此指向Foo对象的指针不会失效。

使用指针向量

或者,您可以使用std::vector<std::unique_ptr<Foo>>代替std::vector<Foo> 这样,即使向量重新分配了其元素,指向的Foo对象的地址也不会更改,因为它将是将要重新分配的std:unique_ptr<Foo>对象,而不是Foo对象。 因此,指向Foo对象的指针仍然有效。


后一种方法引入了附加的间接层,因此,效率比前一种低。

您有四种可能性:

  • 您使用非无效容器。 那是你的建议。

  • 您事先在向量中保留了足够的空间( El教授的答案 )。 仅当您事先知道Foo的最大数量时,此方法才有效。

  • 您使用(智能)指针的向量( Michael Chourdakis的答案 )。 只要您不需要将指针用作迭代器,此方法就起作用。

  • 您无需对vector<Foo>进行任何更改,但可以使索引使用算法来代替指针。 这使您可以查看元素的前后(检查向量边界之后),并且索引不会因重新分配而无效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM