2017-06-06 32 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'是否將迭代器返回給函數local'list'? – Praetorian

+0

這不是C++異常,因此您無法捕捉它。只有當'SearchAccount'返回另一個列表的迭代器時,您纔有此行的未定義行爲。 – Rakete1111

+0

我在問題 – axcelenator

回答

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

而現在你沒有異常機制的開銷,併發生「正確的事情」。

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塊沒有必要。然而,無效的迭代器會導致未定義的行爲。

你可以在for循環後SearchAccount回到Acc.end()和檢查返回值是否是Acc.end,而不是使用try