为什么在擦除位置之前的矢量的 c++ 迭代器在 Visual Studio 中也失效
Why c++ iterators of vector before erase position are also invalidated in visual studio?
int removeDuplicates(vector<int>& nums) {
vector<int>::iterator iter = nums.begin();
vector<int>::iterator test = nums.begin(); //used to test
while (nums.begin() != nums.end())
{
vector<int>::iterator temp = iter;
vector<int>::iterator temp2 = ++iter;
if (temp2 == nums.end()) break;
if (*temp == *temp2)
{
iter = nums.erase(temp);
cout << *test << " "; //test here, error happen
}
}
return nums.size();
}
int main()
{
vector<int> test = { 1,1,2,2,4,5,6,6 };
int result = removeDuplicates(test);
}
错误消息:"vector iterator not dereferencable!"
我看过一些文章说"擦除位置之前的迭代器保持有效,只有擦除位置后的迭代器变得无效。
但是当我尝试使用上面的代码时,我发现擦除位置也变得无效之前的迭代器,我不知道为什么。请帮忙!
vector<int>::iterator iter = nums.begin(); vector<int>::iterator test = nums.begin(); vector<int>::iterator temp = iter;
temp
,iter
和test
指向同一个元素。
iter = nums.erase(temp);
该元素将被擦除。这使temp
和test
无效。 但是,iter
被重新分配给下一个元素。
cout << *test << " ";
无效的test
是不可竖立的。行为是不确定的。
只要在第一次迭代中*temp == *temp2
为真,就会重现这种情况。在以后的迭代中,iter
和 temp
不再指向第一个元素。
这应该对您有所帮助。
int removeDuplicates(std::vector<int>& nums)
{
for (auto iter = nums.begin(); iter != nums.end(); /* DO NOT INCREMENT */)
{
if (std::find(iter + 1, nums.end(), *iter) != nums.end())
{
iter = nums.erase(iter);
}
else
{
++iter;
}
}
return static_cast<int>(nums.size());
}
cppreference.com 对vector::erase
说了以下内容:
使擦除点处或之后的迭代器和引用失效,包括 end() 迭代器。
所以在你的例子中,test
和temp
都是用nums.begin()
初始化的。当您擦除temp
时,这将temp
无效。因此,您需要确保重新初始化temp
,或者保留已删除元素的副本以供以后使用。
那么像这样更改代码怎么样:
int removeDuplicates(vector<int>& nums) {
vector<int>::iterator iter = nums.begin();
vector<int>::iterator test = nums.begin(); //used to test
while (nums.begin() != nums.end())
{
vector<int>::iterator temp = iter;
vector<int>::iterator temp2 = ++iter;
size_t dist = std::distance(nums.begin(), temp);
if (temp2 == nums.end()) break;
if (*temp == *temp2)
{
iter = nums.erase(temp);
test = nums.begin();
test += dist;
cout << *test << " "; //test here, error happen
}
}
return nums.size();
}
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- 为什么在擦除位置之前的矢量的 c++ 迭代器在 Visual Studio 中也失效
- 矢量迭代器在 Visual Studio 中不可延迟
- 找不到Microsoft Visual Studio 2010 c++矢量迭代器.base
- Visual Studio 2013 调试迭代器容器
- Visual Studio检查了迭代器不抛出异常
- C++,Visual Studio 2015,矢量迭代器不可取消引用
- 迭代器擦除 (迭代器在先,迭代器最后) 在 Visual C++ 2010 Express 下不起作用
- Visual Studio中的std::transform在使用自己的迭代器时会失败
- 仅visual studio 2010中存在可延迟迭代器问题
- G++ 4.6 抱怨迭代器差异类型。g++ 4.4 和 Visual Studio 没有
- visual C++标准是否要求自己的迭代器是另一个可移动/可复制的
- Visual C++,使用相同迭代器名称的多个for循环,在调试模式下在范围外可见