2012-03-30 19 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,但显然我“无权提交反馈此连接。”