2012-03-30 32 views
2

在try塊中,我使用新的本機對象填充std :: list。在我的finally塊中,我遍歷了刪除每個本地對象的列表。try-catch-finally中的C++/CLI迭代器異常

當我最後迭代時,我得到一個「Expression:list iterators incompatible」斷言。

我創建了3種測試方法:

  1. 外的try-catch-終於方法返回。這運行良好。
  2. 方法返回try中。最終迭代時會得到異常。
  3. 方法返回try中,但我刪除了catch。這只是我碰巧發現並無法解釋的事情。但是這個也運行良好。

有人可以解釋這裏發生了什麼,最好的解決辦法嗎? 我已經上傳a very simple test solution here

這是一個VS2010解決方案。該應用程序是一款面向64位的WPF應用程序,但如果需要可以輕鬆更改。

編輯: 下面是CLI代碼,演示上述3種情況。

int CLITryCatchFinallyBug_CLI::CliClass::Test1() 
{ 
    // RETURNS AT END. RUNS FINE. 

    std::list<NativeClass*> nativeClassList; 

    try 
    {  

     for(int i=0; i<10; i++) 
     { 
      nativeClassList.push_back(new NativeClass(100,200)); 
     } 

     // NOTICE RETURN IS AT END. 
    } 
    catch(std::exception& e) 
    { 

    } 
    finally 
    { 
     // Delete the native objects. 
     std::list<NativeClass*>::iterator deleteIterator; 
     for (deleteIterator = nativeClassList.begin(); 
      deleteIterator != nativeClassList.end(); 
      deleteIterator++) 
     { 
      delete *deleteIterator; 
     } 
    } 

    return 1; 
} 

int CLITryCatchFinallyBug_CLI::CliClass::Test2() 
{ 
    // RETURN WITHIN TRY. GETS EXCEPTION IN FINALLY. 

    std::list<NativeClass*> nativeClassList; 

    try 
    {  

     for(int i=0; i<10; i++) 
     { 
      nativeClassList.push_back(new NativeClass(100,200)); 
     } 

     // NOTICE RETURN IS HERE WITHIN TRY 
     return 1; 
    } 
    catch(std::exception& e) 
    { 

    } 
    finally 
    { 
     // Delete the native objects. 
     std::list<NativeClass*>::iterator deleteIterator; 
     for (deleteIterator = nativeClassList.begin(); 
      deleteIterator != nativeClassList.end(); 
      deleteIterator++) // WILL GET EXCEPTION HERE! 
     { 
      delete *deleteIterator; 
     } 
    } 
} 

int CLITryCatchFinallyBug_CLI::CliClass::Test3() 
{ 
    // SAME AS TEST 2 BUT WITHOUT THE CATCH BLOCK. NO EXCEPTION. 

    std::list<NativeClass*> nativeClassList; 

    try 
    {  

     for(int i=0; i<10; i++) 
     { 
      nativeClassList.push_back(new NativeClass(100,200)); 
     } 

     // NOTICE RETURN IS HERE WITHIN TRY 
     return 1; 
    } 
    // NOTICE THIS IS THE SAME AS TEST2 EXCEPT I'VE REMOVED THE CATCH 
    finally 
    { 
     // Delete the native objects. 
     std::list<NativeClass*>::iterator deleteIterator; 
     for (deleteIterator = nativeClassList.begin(); 
      deleteIterator != nativeClassList.end(); 
      deleteIterator++) // UNLIKE TEST2, NO EXCEPTION 
     { 
      delete *deleteIterator; 
     } 
    } 
} 
+4

與其讓人們下載整個解決方案,不能創建一個簡短但完整的控制檯應用程序,您可以在問題中發佈? – 2012-03-30 14:47:51

+0

如果你在中間返回,那麼你的std :: list在方法級別的作用域可能已經在達到finally塊的時候被清除了(它的析構函數被調用了)。 – 2012-03-30 17:26:46

+2

在我之後重複:「這是C++,我將使用RAII來實現異常安全,而不是嘗試最終,我將使用RAII來實現異常安全,而不是嘗試最終。 – 2012-03-30 18:44:21

回答

0

我在VS 2013中看到了同樣的問題。似乎C++/CLI異常處理實現太早破壞本機C++類型。只有在catch塊和try塊有明確的返回時纔會發生異常。

const CString foo = "foo"; 
try 
{ 
    return; 
} 
catch (Exception^ ex) 
{ 
} 
finally 
{ 
    const CString bar = foo; // AccessViolationException 
} 

我試圖report the bug到MS,但顯然我「無權提交反饋此連接。」