[英]How to properly keep track of addresses using STL?
背景
我有一個對象向量和一個按名稱(字符串)指向這些對象的索引(映射)。 在我的情況下,向量只會增長(從不刪除項目)。
我不知道這個
struct Foo { };
std::vector<Foo> v;
std::map<std::string,Foo*> m; // addresses are &v[0], &v[1], etc...
因為我添加項目到v
,老映射在m
有可能成為無效應該v
來realloc'ed。
題
如果我通過添加額外的抽象級別std::unique_ptr<>
將m
是確定應v
被realloc'ed?
struct Foo { };
std::vector<std::unique_ptr<Foo>> v;
std::map<std::string,Foo*> m; // addresses are v[0].get(), v[1].get(), etc...
由於復制省略,我認為答案是肯定的,但我不確定。
簡短答案:是,但與復制省略無關
在第一種情況下,為向量分配的內存是Foo的連續數組。 正如您所暗示的,當增大向量時,如果當前數組的容量不夠大,則會分配一個新數組,並且索引中的指針仍指向舊地址。
// let x be sizeof(Foo)
Adresses 10 10+x 10+2x
Type [ Foo | Foo | Foo ]
重新分配發生
Adresses 30 30+x 30+2x 30+3x
Type [ Foo | Foo | Foo | Foo ]
如您所見,在地址10上不再找到第一個Foo
對象。
使用第二種方法時,您不是通過值將Foo存儲在向量中,而是通過指針存儲。 假設您在免費存儲區中為指向的Foo對象正確分配了內存,則不需要移動該對象。 當Vector增大並需要重新分配時,它將為您的Foo對象分配一個新的(唯一)指針數組,unique_ptr的地址將更改(如果需要,您的Foo **),這些對象將保留在相同的地址和以前一樣(Foo *相同)。
// let y be sizeof(Foo*)
Adresses 10 10+y 10+2y .. 50 .. 60 .. 90
Type [ Foo* | Foo* | Foo* ] [Foo] [Foo] [Foo]
Value ( 50 60 90 )
重新分配發生
Adresses 30 30+y 30+2y 30+3y .. 50 .. 60 .. 90 .. 110
Type [ Foo* | Foo* | Foo* | Foo* ] [Foo] [Foo] [Foo] [Foo]
Value ( 50 60 90 110 )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.