Why does this program crash: passing of std::string between DLLs

This isn’t actually being caused by differing heap implementations – the MSVC std::string implementation doesn’t use dynamically allocated memory for strings that small (it uses the small string optimization). The CRTs do need to match, but that isn’t what bit you this time.

What’s happening is that you’re invoking undefined behaviour by violating the One Definition Rule.

The release and debug builds will have different preprocessor flags set, and you’ll find that std::string has a different definition in each case. Ask your compiler what sizeof(std::string) is – MSVC10 tells me that it’s 32 in a debug build and 28 in a release build (this isn’t padding – 28 and 32 are both 4 bytes` boundaries).

So what’s happening? Variable s is initialized using the debug version of the copy constructor to copy a release version of std::string. The offsets of the member variables are different between the versions, so you copy garbage. The MSVC implementation effectively stores begin and end pointers – you’ve copied garbage into them; because they’re no longer null, the destructor tries to free them and you get an access violation.

Even if the heap implementations were the same it would crash, as you’re freeing garbage pointers to memory that was never allocated in the first place.


In summary: the CRT versions need to match but so do the definitions – including the definitions in the standard library.

Leave a Comment