[英]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.