![](/img/trans.png)
[英]std::vector::shrink_to_fit() does not check allocator equality
[英]Is it safe to compare to pointer of std::vector to check equality?
一次,我創建了一個指向std::vector
的指針,然后我對該向量做了一些push_back
, reserve
, resize
操作,在這樣的操作之后,將指針與該向量的地址進行比較以檢查是否安全指針指向該向量,因為可能存在一些內存重新分配。
例如
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::vector
的operator =
。 因此,兩個assert(pVec == &vec);
成功通過。
在int* p = &vec[0];
這取決於:看到Iterator invalidation
。
第一種情況確實是安全的,因為矢量對象的地址沒有變化的危險。 第二種情況是安全的,只要沒有重新分配(使用std :: vector :: capacity成員函數可以跟蹤重新分配),否則它是未定義的或實現定義的,具體取決於語言的版本。 有關更多信息, 請參閱此答案。 因為同樣的限制適用於那種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.