std :: list :: erase(iter)异常处理c ++

时间:2017-06-06 15:36:10

标签: c++ list exception-handling iterator

我尝试从函数中获取迭代器,然后从列表中删除元素。

  1. 有没有办法赶上那个例外?
  2. 有没有办法知道迭代器是否有效?
  3. 当我使用无效迭代器运行程序时,它会抛出以下异常:

     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;
        }
    
    }
    

3 个答案:

答案 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