我有一个向量的迭代器,我想删除向量中的某些元素。运行代码时,编译中没有出现错误,但在执行后我收到一条消息,说“调试断言失败了!”#39;。有人能告诉我迭代器有什么问题吗?
int function(unsigned int n, unsigned int m)
{
vector<int> vec1;
vec1.push_back(3);
vec1.push_back(4);
vec1.push_back(5);
vector<int>::iterator vec2;
for (vec2 = vec1.begin(); vec2 != vec1.end(); ++vec2)
{
if(*vec2 == 4)
{
vec1.erase(vec2);
}
}
return 0;
}
答案 0 :(得分:4)
erase
方法会使迭代器无效。你必须写:
for (vec2 = vec1.begin(); vec2 != vec1.end(); )
{
if(*vec2 == 4)
vec2 = vec1.erase(vec2);
else
++vec2;
}
请注意,仅当元素不是vec2
时,您才必须增加erased
。如果在每次迭代时增加vec2
,则会遗漏一些元素,因为erase
返回一个指向已擦除元素旁边元素的迭代器。
答案 1 :(得分:1)
问题是您要从正在迭代的向量中删除。从向量中删除对象后,其所有迭代器都将失效;后续访问它们是未定义的行为。
要解决此问题,您可以使用索引,并从末尾开始遍历向量。这样,无论是否删除了对象,都可以在每次迭代时递减索引。
答案 2 :(得分:1)
向量元素存储在连续的内存中,因此当您擦除向量的元素时,尾元素(擦除元素之后的元素)必须“移位”,因此向量的所有迭代器都会失效。
答案 3 :(得分:0)
删除所有等于某个值的元素的常用方法是使用标准算法std::remove
以及成员函数erase
例如
void function()
{
vector<int> vec1;
vec1.push_back(3);
vec1.push_back(4);
vec1.push_back(5);
vec1.erase( std::remove( vec1.begin(), vec1.end(), 4 ), vec1.end() );
}
如果你只想删除一个等于4的元素,你可以写
void function()
{
vector<int> vec1;
vec1.push_back(3);
vec1.push_back(4);
vec1.push_back(5);
auto it = std::find( vec1.begin(), vec1.end(), 4 );
if ( it != vec1.end() ) vec1.erase( it );
}
如果要使用循环删除所有等于4的元素,则应编写
void function()
{
vector<int> vec1;
vec1.push_back(3);
vec1.push_back(4);
vec1.push_back(5);
for ( auto it = vec1.begin(); it != vec1.end(); )
{
if ( *it == 4 ) it = vec1.erase( it );
else ++it;
}
}