簡體   English   中英

std :: vector指針可靠嗎?

[英]Is a std::vector pointer reliable?

說我有這個:

Object *myObject;
std::vector<Object> objects(99);

....
myObject = &objects[4];

可以安全地假設myObject的指針將始終有效,無論有多少大的object [],如果我刪除了一些對象,只要我從不擦除myObject指向的實際對象,就可以了嗎? 還是不同地工作? 如果上述方法不起作用,我還能怎么實現呢? 這是因為在我的設計中,我希望孩子有一個指向其父對象的指針,該指針是在添加孩子時由父對象分配的,但是父對象位於std :: vector中,我需要隨機訪問。 在我看來,std :: list會更好嗎?

謝謝

不,假設絕對不安全。

該標准說明了將/不會使標准容器上的迭代器無效的內容; 每當向量迭代器失效時,指向它的指針也將變為無效。 實際上,這意味着當向量調整大小時(包括在調用push_back()時隱式包含),指向該向量的任何迭代器都會失效,指針也將無效。 同樣,在調用被擦除的項之后,調用erase()將使指針無效,因為它們都必須向上移動以填充被擦除的空間。

一個std::list會更好; 您可以並行維護指向項目的指針向量,這將使您可以通過索引訪問它們,而無需在內存中移動它們。

如果向量填滿了分配的空間,而您嘗試插入更多空間,則需要重新分配其存儲,這將涉及復制對象並破壞舊的存儲,這將使您保留的指針無效-因此不,這還不夠好。

std :: list可以正常工作,因為它不依賴於連續存儲,但是您失去了進行快速隨機訪問的能力。 另外,您可以在集合中存儲指向對象的指針,在這種情況下,您可以刪除該元素,並且指針將一直有效,直到您在代碼中釋放該內存為止-但您需要在某個時候自行處理。

另一個選擇可能是雙端隊列 盡管雙端隊列迭代器被push_back無效,但對元素的直接引用(例如您在此處使用的指針)仍然有效。

如果向量保持相同大小,則可以通過在聲明它之后或通過(如您所進行的)聲明初始數量的元素(每個構造為具有默認元素值reserve()的最大數量的元素來調用reserve()來保證這一點。 。

如果刪除或添加元素,則可以隨時重新分配基礎存儲。

由於您在此處使用原始指針,因此可以將NULL用作“空元素”標志,以保持存儲不變。 由於您最初將其設置為99,因此之后它們都將為NULL(任何指針作為矢量元素的默認值),並且reserve是多余的,除非您打算擴展列表。

一個讓您不必擔心向量存儲的選項是將元素存儲為boost::shared_ptr<Object> 然后,如果沒有其他人使用vector元素,則僅deletedelete實際上delete引用的Object實例。

boost::shared_ptr<Object> myObject;
std::vector<boost::shared_ptr<Object> > objects(99);

myObject = &objects[4];

objects.clear();
// myObject still valid since Object instance referenced thru shared_ptr

奇怪,但是沒有人提到boost :: stable_vector事情:

...只要未擦除穩定元素的元素的引用和迭代器就一直有效,並且分配了end()返回值的迭代器始終保持有效,直到關聯的穩定向量被破壞為止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM