簡體   English   中英

比較std :: vector的指針以檢查相等性是否安全?

[英]Is it safe to compare to pointer of std::vector to check equality?

一次,我創建了一個指向std::vector的指針,然后我對該向量做了一些push_backreserveresize操作,在這樣的操作之后,將指針與該向量的地址進行比較以檢查是否安全指針指向該向量,因為可能存在一些內存重新分配。

例如

std::vector<int> vec;
vector<int>* pVec = &vec;
vec.reserve(10000);
assert(pVec == &vec);
vec = anotherVec;
assert(pVec == &vec);

更重要的是,將指針與向量的第一個值進行比較是否安全? 例如:

std::vector<int> vec(1,0);
int* p = &vec[0];
// some operation here
assert(p == &vec[0]);

正如我自己測試的那樣,第一種情況似乎是安全的,而第二種情況則不然,但我不能確定。

std::vector<int> vec;
vector<int>* pVec = &vec;
vec.reserve(10000);
assert(pVec == &vec);

是安全的。


std::vector<int> vec(1,0);
int* p = &vec[0];
// some operation here
assert(p == &vec[0]);

不安全


第一個塊是安全的,因為即使內容發生變化,地址vec也不會改變。

第二個塊不安全,因為vec[0]的地址可能會改變; 例如,當vec調整自身大小時 - 例如,當你將元素推送到它時。

似乎第一種情況是安全的,而第二種情況則不然

那就對了。 在第一個“情境”中,無論reserve調用如何, vec對象本身都保留在內存中的任何位置,這可能會將托管元素移動到動態內存的另一個區域。 這是因為在第二種情況下可以移動指針可能無法比較的元素。

只要不進行搬遷 ,第二種情況就是安全的。 如果您在獲得指針之前知道了預先需要的大小並使用reserve() ,那么它是非常安全的,您可以節省一點性能(一個較低的間接級別)。

但是,任何使用push_back()的添加都可能超出分配的空間並使指針無效。 std::vector已經過優化,如果可能的話,會嘗試在同一位置分配更多的內存(因為它可以節省復制數據),但你無法確定。

就此而言,不是采用指針,而是可以使用迭代器,因為向量上的迭代器的行為與指針完全相同(並且沒有性能影響),具有更多的類型安全性。

vector<int>* pVec = &vec; std::vector<int>對象的地址進行操作,該對象有效直到范圍。 vec = anotherVec; 不會改變vec的地址,因為這里調用了std::vectoroperator = 因此,兩個assert(pVec == &vec); 成功通過。

int* p = &vec[0]; 這取決於:看到Iterator invalidation

第一種情況確實是安全的,因為矢量對象的地址沒有變化的危險。 第二種情況是安全的,只要沒有重新分配(使用std :: vector :: capacity成員函數可以跟蹤重新分配),否則它是未定義的或實現定義的,具體取決於語言的版本。 有關更多信息, 請參閱此答案。 因為同樣的限制適用於那種情況。

暫無
暫無

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

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