Прервать в деструкторе

Следующий код C ++ получает загадочную ошибку («Ошибка отладки! … abort () была вызвана»), когда return выполнен. Это Visual Studio 2017 15.6.3, и программа представляет собой отладочную 64-битную сборку, работающую под 64-битной Windows 7. Что является причиной этой ошибки и как ее исправить?

wifstream inFile;

std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian> cv1;
inFile.imbue(std::locale(inFile.getloc(), &cv1));
return 0;

Трассировка с помощью отладчика показывает, что сообщение исходит из инструкции дизассемблера

call        std::basic_ifstream<wchar_t,std::char_traits<wchar_t> >::`vbase destructor'

Последняя запись в стеке, кроме msvcp140d.dll, vcruntime140d.dll а также ucrtbased.dll является

    MyApp.exe!std::basic_ifstream<wchar_t,std::char_traits<wchar_t> >::`vbase destructor'() C++

Целью этого кода является входной файл infile Unicode (little-endian), и я читаю его в std::string переменная.

0

Решение

std::locale поддерживает счетчик ссылок для каждого фасета, который связан с ним. std::locale конструктор, который вы вызываете, будет увеличивать счетчик ссылок для std::codecvt_utf16 объект, который вы передаете, а затем std::localeДеструктор уменьшит этот счетчик ссылок. Когда счетчик ссылок std::codecvt_utf16 падает до 0, он будет уничтожен через delete оператор. Вот почему вы получаете ошибку прерывания — когда std::wifstream деструктор убирает imbueДеструктор локали пытается delete то, что не было выделено с new оператор для начала.

Сделайте это вместо этого:

inFile.imbue(std::locale(inFile.getloc(),
new std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>));

Смотрите пример в std::codecvt_utf16 документация по cppreference.com.

1

Другие решения

Других решений пока нет …