2
在try块中,我使用新的本机对象填充std :: list。在我的finally块中,我遍历了删除每个本地对象的列表。try-catch-finally中的C++/CLI迭代器异常
当我最后迭代时,我得到一个“Expression:list iterators incompatible”断言。
我创建了3种测试方法:
- 外的try-catch-终于方法返回。这运行良好。
- 方法返回try中。最终迭代时会得到异常。
- 方法返回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;
}
}
}
与其让人们下载整个解决方案,不能创建一个简短但完整的控制台应用程序,您可以在问题中发布? – 2012-03-30 14:47:51
如果你在中间返回,那么你的std :: list在方法级别的作用域可能已经在达到finally块的时候被清除了(它的析构函数被调用了)。 – 2012-03-30 17:26:46
在我之后重复:“这是C++,我将使用RAII来实现异常安全,而不是尝试最终,我将使用RAII来实现异常安全,而不是尝试最终。 – 2012-03-30 18:44:21