The following C++ code gets a mysterious error ("Debug Error!...abort() has been called") when the return
is executed. This is Visual Studio 2017 15.6.3, and the program is a 64-bit debug build, running under 64-bit Windows 7. What is causing this error, and how can I fix it?
wifstream inFile;
std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian> cv1;
inFile.imbue(std::locale(inFile.getloc(), &cv1));
return 0;
Tracing through with the debugger shows the message is coming from the disassembler instruction
call std::basic_ifstream<wchar_t,std::char_traits<wchar_t> >::`vbase destructor'
The last entry on the stack, other than msvcp140d.dll
, vcruntime140d.dll
and ucrtbased.dll
is
MyApp.exe!std::basic_ifstream<wchar_t,std::char_traits<wchar_t> >::`vbase destructor'() C++
The purpose of this code is the input file infile
is Unicode (little-endian), and I am reading it into a std::string
variable.
std::locale
maintains a reference count for each facet that is associated with it. The std::locale
constructor you are calling will increment a reference count for the std::codecvt_utf16
object you are passing in, and then std::locale
's destructor will decrement that reference count. When the reference count of the std::codecvt_utf16
falls to 0, it will be destroyed via the delete
operator. That is why you are getting the abort error - when the std::wifstream
destructor is cleaning up the imbue
'd locale, the locale's destructor tries to delete
something that was not allocated with the new
operator to begin with.
Do this instead:
inFile.imbue(std::locale(inFile.getloc(),
new std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>));
See the example in the std::codecvt_utf16
documentation on cppreference.com.