Следующий код 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
переменная.
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.
Других решений пока нет …