我尝试从函数中获取迭代器,然后从列表中删除元素。
当我使用无效迭代器运行程序时,它会抛出以下异常:
Exception thrown: read access violation.
_Right.**_Myproxy** was 0xCCCCCCCC. occurred
我的功能是:
list<AccountStruct>::const_iterator SearchAccount(list<AccountStruct>& Acc,string p)
{
for (list<AccountStruct>::const_iterator j = Acc.begin(); j !=Acc.end(); ++j)
{
if ((*j).phone == p) return j;
}
}
void RemoveAccount(list<AccountStruct>& Acc)
{
string Phone;
cout << "Enter Phone Number ->" << endl;
cin >> Phone;
//cout << "Searching..." << endl;
list<AccountStruct>::const_iterator iter = SearchAccount(Acc,Phone);
try
{
Acc.erase(iter);
}
catch()// <- What to put inside??
{
cout << "No Phone Number;" << endl;
}
}
答案 0 :(得分:0)
我们可以通过一些修改来解决这个问题。首先,如果函数找不到对象,SearchAccount
不会返回任何内容。这是未定义的行为,因为当你说你愿意时你必须返回一些东西。如果找不到像end()
这样的项目,我们可以通过返回find
来解决此问题。这给了你
list<AccountStruct>::const_iterator SearchAccount(list<AccountStruct>& Acc,string p)
{
for (list<AccountStruct>::const_iterator j = Acc.begin(); j !=Acc.end(); ++j)
{
if ((*j).phone == p) return j;
}
return Acc.end(); // item not found
}
现在SearchAccount
正常运行,我们可以检查是否返回end()
而不是使用异常机制。看起来像
void RemoveAccount(list<AccountStruct>& Acc)
{
string Phone;
cout << "Enter Phone Number ->" << endl;
cin >> Phone;
//cout << "Searching..." << endl;
list<AccountStruct>::const_iterator iter = SearchAccount(Acc,Phone);
if (iter != Acc.end())
{
Acc.erase(iter);
}
else
{
cout << "No Phone Number;" << endl;
}
}
现在你没有异常机制的开销,并且“正确的事情”发生了。
答案 1 :(得分:0)
您应该使用::std::remove_if
algorithm
Acc.erase
(
::std::remove_if
(
Acc.begin()
, Acc.end()
, [&Phone](AccountStruct const & acc)
{
return(acc.phone == Phone);
}
)
, Acc.end()
);
答案 2 :(得分:0)
std::list::erase
不会抛出任何异常。
不需要try
块。但是,无效的迭代器将导致未定义的行为。
您可以在Acc.end()
的{{1}}循环之后返回for
,并针对SearchAccount
检查返回的值,而不是使用Acc.end
。