簡體   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