[英]Vector iterator inconsistent and Expression: cannot seek vector iterator after end
我試圖在每 5 個元素之后向向量添加一個值。 這個例子給了我一個斷言錯誤Expression: cannot seek vector iterator after end
該錯誤是不言自明的,但是代碼在在線編譯器中執行並給出了所需的結果。 我可以少做 1 次迭代,在這種情況下,最終插入不會發生並返回錯誤。 我也知道創建一個結構將是解決這個問題的更好方法,但我想知道我是如何/為什么在這個迭代器方法上苦苦掙扎的。
vertexSize 在每種情況下均分到 targetBuffer 中,因此這不是問題。
//error example
int vertexSize = 5;
int size = targetBuffer.size() / vertexSize;
std::cout << targetBuffer.size() << std::endl;
std::cout << vertexSize << std::endl;
std::vector<float>::iterator it;
it = targetBuffer.begin() + vertexSize;
std::cout << std::distance(targetBuffer.begin(), it) << std::endl;
for (int i = 0; i < size; i++) {
it = targetBuffer.insert(it, (unsigned int)(i * vertexSize) / (24 * vertexSize));
it += vertexSize + 1;
}
但是,如果我在在線編譯器中運行下面的示例,它會運行並給出所需的結果。
int vertexSize = 3;
std::vector<int> targetBuffer;
for(int i = 0; i < 1002; i++){
targetBuffer.push_back(-1);
}
int size = targetBuffer.size() / 3;
for (int i = 0; i < 110; i++) {
std::cout << i <<":" << " " << targetBuffer[i] << std::endl;
}
std::vector<int>::iterator it;
it = targetBuffer.begin() + vertexSize;
for (int i = 0; i < size; i++) {
//(unsigned int)(i*5)/(24*5)
it = targetBuffer.insert(it, (unsigned int)(i * vertexSize) / (24 * vertexSize));
std::advance(it, 3);
}
std::cout << "NEW SIZE " << targetBuffer.size() << std::endl;
for (int i = 0; i < 110; i++) {
std::cout << i <<":" << " " << targetBuffer[i] << std::endl;
}
for (int i = 900; i < targetBuffer.size(); i++) {
std::cout << i <<":" << " " << targetBuffer[i] << std::endl;
}
原始矢量
0: -1
1: -1
2: -1
3: -1
4: -1
5: -1
6: -1
7: -1
8: -1
初始迭代器
it = targetBuffer.begin() + vertexSize;
插入屬性
it = targetBuffer.insert(it, (unsigned int)(i * vertexSize) / (24 * vertexSize));
it += vertexSize + 1;
0: -1
1: -1
2: -1
3: 0
4: -1
5: -1
6: -1
7: 0
8: -1
9: -1
10: -1
11: 0
所以我對使用迭代器有一些觀察。 如果我從添加中刪除 +1,則它只插入 2 個位置而不是 3 個,如下所示。 但是第一個插入在 3 個空格之后。
it = targetBuffer.insert(it, (unsigned int)(i * vertexSize) / (24 * vertexSize));
it += vertexSize;
0: -1
1: -1
2: -1
3: 0
4: -1
5: -1
6: 0
7: -1
8: -1
9: 0
我的猜測是,這是由於調整向量和迭代器的大小而沒有考慮新添加的值或類似的東西? 也許我應該在循環的每次迭代中重新評估迭代器,即
for(...)
it = targetBuffer.begin() + i * vertexSize;
或類似的東西
問題很簡單,即使您從不嘗試取消引用結果,也禁止將迭代器遞增到結束迭代器之外。
當你寫std::advance(it, 3);
或者it += vertexSize + 1;
並且原始向量的大小不能被您選擇的步長整除, it
的結果值可能會超出最后一次循環迭代中向量的末尾。 因為它是最后一次循環迭代,您實際上並沒有重新進入循環體並使用it
的值,但根本不允許首先形成這個迭代器,這樣做會導致未定義的行為。 它有時會起作用並不會改變這一點。 (這就是未定義行為的問題。有時它可能會起作用,但絕對不能保證它的行為方式。)
您可以通過重寫循環來解決此問題,以便在插入之前首先增加循環中的迭代器,以便刪除當前在最后一次循環迭代中存在的有問題的增量:
it = targetBuffer.begin();
for (int i = 0; i < size; i++) {
std::advance(it, vertexSize);
it = targetBuffer.insert(it, (unsigned int)(i * vertexSize) / (24 * vertexSize));
// `insert` inserts _before_ the passed iterator,
// so get back to that element
std::advance(it, 1);
}
但是,這種算法的性能很差。 它的時間復雜度是向量長度的二次方。 最好創建一個新向量,在其上調用.reserve
(或.resize
)以保留正確的大小,然后循環遍歷向量和.push_back
舊元素和新元素的副本(或對其進行索引而不是使用.push_back
)。 最后移動分配或將新向量與舊向量交換。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.