2017-06-06 23 views
0

関数からイテレータを取得し、リストから要素を消去しようとしました。std :: list :: erase(iter)例外処理C++

  1. この例外を検出する方法はありますか?
  2. イテレータが有効かどうかを知る方法はありますか?

私は、無効なイテレータでプログラムを実行すると、それは次の例外スロー:

Exception thrown: read access violation. 
_Right.**_Myproxy** was 0xCCCCCCCC. occurred 

マイfuncがある:

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

あなたの時間は、アクセス違反の原因を突き止めるために費やされた時間です。 'SearchAccount'はイテレータをローカルの' list'関数に返しますか? – Praetorian

+0

C++の例外ではないので、あなたはそれをキャッチできません。 'SearchAccount'が別のリストのイテレータを返す場合にのみ、この行に未定義の動作があります。 – Rakete1111

+0

質問に別の関数を追加しました – axcelenator

答えて

0

我々はカップルの変更でこの問題を解決することができます。まず、SearchAccountは、関数がオブジェクトを見つけられなかった場合は何も返しません。あなたが言うときに何かを返さなければならないので、これは未定義の振る舞いです。 findのような項目が見つからない場合はend()を返すことで修正できます。それは今でSearchAccount機能が正しく、我々はその後、end()は、例外メカニズムを使用する代わりに返されたかどうかを確認することができますあなたの

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 
} 

を与えます。それは

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

ように見えるそして今、あなたは例外メカニズムのオーバーヘッドと起こる「正しいこと」を持っていません。

0

あなたは、任意の例外をスローしません::std::remove_if algorithm

Acc.erase 
(
    ::std::remove_if 
    (
     Acc.begin() 
    , Acc.end() 
    , [&Phone](AccountStruct const & acc) 
     { 
      return(acc.phone == Phone); 
     } 
    ) 
, Acc.end() 
); 
0

std::list::eraseを使用する必要があります。

ブロックtryブロックは必要ありません。しかし、無効なイテレータは未定義の動作を引き起こします。

あなたはSearchAccountforループの後でAcc.end()を返し、代わりにtryを使用してのAcc.endに対して返された値をチェックすることができます。