Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::string[] member deallocation fails during exception thrown from constructor

Using Visual Studio 2015 (update 3) I have a problem in a larger project which i boiled down to the minimal example down below.

Therein i have a class Test containing a std::string[3]. It may so happen, that the constructor of Test throws an exception, which i would like to deal with at the top level (main). However, when throwing from the constructor, an assertion in xmemory fails - it seems to me while trying to unwind and deallocate the std::string[3] (see console output and stack trace below). The catch statement is never reached and in a release built it just crashes.

When i replace the std::string[3] by a single std::string, the catch statement is correctly reached. Also, when throwing an exception from another member function called externally after construction is finished the catch block is reached as expected if using std::string[3].

What is going on here? Any help appreciated.

The minimal example:

#include "stdafx.h"
#include <vcruntime_exception.h>
#include <string>
#include <iostream>



class Test {
public:
    Test() {
        // throw exception from constructor
        throw std::exception("TestException");
    }

    ~Test() {
        std::cout << "Destruction" << std::endl;
    }

    //std::string mySingleString = "SingleTestString";
    std::string myStrings[3] = { "String1", "TestString2", "AnotherTestString" };
};


int main()
{
    try
    {
        Test* t = new Test();
    }
    catch (std::exception& e)
    {
        // this is never reached while std::string myStrings is not uncommented
        std::cout << "Caught:" << e.what() << std::endl;
    }
    catch (...) {
        std::cout << "Caught an alien!" << std::endl;
    }
    return 0;
}

The console output:

Ausnahme ausgelöst bei 0x773CDDC2 in ConsoleApplication1.exe: Microsoft C++-Ausnahme: std::exception bei Speicherort 0x0019FB8C.
"ConsoleApplication1.exe" (Win32): "C:\Windows\SysWOW64\kernel.appcore.dll" geladen. Symbole wurden geladen.
"ConsoleApplication1.exe" (Win32): "C:\Windows\SysWOW64\msvcrt.dll" geladen. Symbole wurden geladen.
"ConsoleApplication1.exe" (Win32): "C:\Windows\SysWOW64\rpcrt4.dll" geladen. Symbole wurden geladen.
"ConsoleApplication1.exe" (Win32): "C:\Windows\SysWOW64\sspicli.dll" geladen. Symbole wurden geladen.
"ConsoleApplication1.exe" (Win32): "C:\Windows\SysWOW64\cryptbase.dll" geladen. Symbole wurden geladen.
"ConsoleApplication1.exe" (Win32): "C:\Windows\SysWOW64\bcryptprimitives.dll" geladen. Symbole wurden geladen.
"ConsoleApplication1.exe" (Win32): "C:\Windows\SysWOW64\sechost.dll" geladen. Symbole wurden geladen.
Debug Assertion Failed!

Program: ...15\Projects\ConsoleApplication1\Debug\ConsoleApplication1.exe
File: c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0
Line: 100

Expression: "(_Ptr_user & (_BIG_ALLOCATION_ALIGNMENT - 1)) == 0" && 0

The stack trace:

ConsoleApplication1.exe!std::_Deallocate(void * _Ptr, unsigned int _Count, unsigned int _Sz) Zeile 99   C++
ConsoleApplication1.exe!std::allocator<char>::deallocate(char * _Ptr, unsigned int _Count) Zeile 720    C++
ConsoleApplication1.exe!std::_Wrap_alloc<std::allocator<char> >::deallocate(char * _Ptr, unsigned int _Count) Zeile 988 C++
ConsoleApplication1.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Tidy(bool _Built, unsigned int _Newsize) Zeile 2260  C++
ConsoleApplication1.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> >() Zeile 1018 C++
ConsoleApplication1.exe!`eh vector destructor iterator'(void * ptr, unsigned int size, unsigned int count, void(*)(void *) destructor)  C++
ConsoleApplication1.exe!_main() C++
ConsoleApplication1.exe!main() Zeile 27 C++
like image 671
Thomas Avatar asked Dec 02 '25 13:12

Thomas


1 Answers

With the help of the commenters this turned out to most likely be a problem with default member initializers and Visual Studio 2015.

Without default initializers it works.

like image 106
Thomas Avatar answered Dec 04 '25 07:12

Thomas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!