我正在尝试编写一个函数,该函数根据该向量元素的account_name从listAccounts中删除向量元素。我写了这个:
void Account::remove_account(string name) {
auto iter = listAccounts.begin();
for ( ; iter != listAccounts.end(); iter++) {
if ((*iter).account_name == name) {
listAccounts.erase(iter);
}
}
}
但是我从矢量删除中得到了分段错误,据我所知,这意味着我试图访问我无法访问的内存,但我不确定如何正确地写这个。 / p>
答案 0 :(得分:2)
删除迭代器指向的元素后,该迭代器将变为无效。 (对于std::vector
,擦除元素之后的所有其他迭代器也变为无效)。并且递增或解除引用无效的迭代器具有未定义的行为。
你可以这样做(假设只删除一个元素):
void Account::remove_account(string name) {
auto iter = std::find_if(listAccounts.begin(), listAccounts.end(),
[&](const auto& s){ return s.account_name == name; });
if(iter != listAccounts.end())
listAccounts.erase(iter);
}
对于多个元素,即:
void Account::remove_account(string name) {
for(auto iter = listAccounts.begin(); iter != listAccounts.end(); ){
iter = std::find_if(iter, listAccounts.end(),
[&](const auto& s){ return s.account_name == name; });
if(iter != listAccounts.end())
iter = listAccounts.erase(iter);
}
}
答案 1 :(得分:2)
如果容器被修改,迭代器将变为无效。 有两个很好的解决方案:
void Account::remove_account(const string& name) {
auto iter = listAccounts.begin();
while iter != listAccounts.end()) {
if (iter->account_name == name) {
iter = listAccounts.erase(iter);
} else {
++iter;
}
}
}
// or
void Account::remove_account(const string& name) {
listAccounts.erase(
std::remove_if(std::begin(listAccounts), std::end(listAccounts),
[&name](const auto& item) {
return item.account_name == name;
}),
std::end(listAccounts));
}
答案 2 :(得分:0)
如果您要删除一个元素,则可以编写
bool Account::remove_account( std::string &name )
{
auto it = std::find_if( listAccounts.begin(),
listAccounts.end(),
[&]( const auto &item )
{
return item.account_name == name;
} );
bool success = it != listAccounts.end();
if ( success ) listAccounts.erase( it );
return success;
}
至于你的代码,然后在这个陈述之后
listAccounts.erase(iter);
迭代器变得无效。所以你可能不会增加它。