2017-02-24 40 views
2
​​

什麼導致此代碼崩潰?我試着用-fsanitize = address編譯它,得到了==9347==ERROR: AddressSanitizer: heap-use-after-free on address 0x61500000fdb4 at pc 0x00010a4f1043 bp 0x7fff55710b70 sp 0x7fff55710b68。當我的電腦上x == 0和y == 22時,它在vec.push_back(x + y)上失敗。基於範圍的循環和std :: vector.push_back()崩潰程序

回答

7

std::vector::push_back

如果新的大小()比容量大(),那麼所有的迭代器和引用(包括過去的最末端迭代器)無效。否則只有最後一個迭代器失效。

基於範圍的循環在內部使用迭代器。使用push_back可能會導致這些迭代器失效。

編輯:請注意,當y == 22您插入第65個元素到您的向量。容量有可能是64.許多實現方式的容量增加2次方(每次增加一倍)。

+0

做一個push_back是UB在循環的任何範圍內還是在循環的內部嵌套範圍內? (你的回答讓我相信「任何範圍的循環」,但這將是一個這樣的陷阱) – user

+2

@user你不能做任何使迭代器無效到你正在使用基於範圍for循環迭代的向量。無效的規則非常明確。例如,你可以在循環內部使用'push_back',以確保size()不會超過'capacity()'(例如,通過使用'reserve()'來提前提高容量)。查看[std :: vector](http://en.cppreference.com/w/cpp/container/vector)的方法頁面,瞭解詳細的失效規則。是的,這是相當的陷阱! –

+0

謝謝你的精度 – user

0

一旦你調用std::vector::push_back或與此有關的迭代器失效最non-const功能(當新的大小超過這將導致存儲在內部重新分配的向量的當前容量)

你可以找到一些一般的標準容器或迭代器是如何工作的很好的參考。我希望你能開始!

+2

有一些非const方法,永遠不會使迭代器失效。例如[std :: vector :: pop_back](http://en.cppreference.com/w/cpp/container/vector/pop_back)或[std :: vector :: back](http://en.cppreference的.com /瓦特/ CPP /容器/載體/背面)。 –

+0

@FrançoisAndrieux或std :: vector :: data。儘管在我看來這是一條很好的經驗法則。大多數非const方法除了直接引用數據的方法外。 – user2176127