Исключение итератора C ++ / CLI в try-catch-finally - PullRequest
2 голосов
/ 30 марта 2012

В блоке try я заполняю список std :: list новыми объектами.В моем блоке finally я перебираю список, удаляя каждый собственный объект.

Я получаю утверждение "Выражение: список итераторов несовместим" при выполнении итерации в моем файле finally.

Я создал 3методы тестирования:

  1. Метод возвращается за пределы try-catch-finally.Это работает нормально.
  2. Метод возвращается в try.Получите исключение при повторении в finally.
  3. Метод возвращается в попытке, но я удалил подвох.Это было просто то, что я случайно обнаружил и не могу объяснить.Но этот тоже работает нормально.

Может кто-нибудь объяснить, что здесь происходит, и лучшее решение?Я загрузил очень простое тестовое решение здесь .

Это решение VS2010.Приложение представляет собой приложение WPF, ориентированное на 64-разрядную версию, но его можно легко изменить при необходимости.

РЕДАКТИРОВАТЬ: вот код 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;
        }
    }   
}

1 Ответ

0 голосов
/ 23 октября 2014

Я видел ту же проблему в VS 2013. Кажется, что реализация обработки исключений в C ++ / CLI слишком рано разрушает собственные типы C ++. Исключение происходит только тогда, когда есть блок catch, а блок try имеет явный возврат.

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

Я пытался сообщить об ошибке в MS, но, очевидно, я "не уполномочен отправлять отзыв об этом соединении".

...