In fact, this is not caused by various heap implementations - the MSVC std :: string implementation does not use dynamically allocated memory for small strings (it uses small string optimizations). CRT needs to be matched, but this time is not what you need.
What happens is that you invoke undefined behavior, breaking the rule of one definition.
In releases and debug builds, different preprocessor flags will be set, and you will find that std::string has a different definition in each case. Ask your compiler that sizeof(std::string) - MSVC10 tells me that it is 32 in the debug build and 28 in the release build (this is not an addition - 28 and 32 are 4 byte boundaries).
So what is going on? The variable s initialized using the debug version of the copy constructor to copy the release version of std::string . Member variable offsets vary between versions, so you are copying garbage. The MSVC implementation effectively saves start and end pointers - you have copied garbage into them; because they are no longer zero, the destructor tries to free them, and you get an access violation.
Even if the heap implementations were the same, it would crash because you are freeing garbage pointers into memory that was never allocated in the first place.
In short: CRT versions should be consistent, but , so definitions - including definitions in the standard library .
Joe Gauterin Feb 23 2018-10-23T00 : 00-23
source share