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