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