Это на самом деле не вызвано различными реализациями кучи - реализация MSVC std :: string не использует динамически выделенную память для маленьких строк (она использует небольшую строковую оптимизацию). ЭЛТ должны совпадать, но на этот раз это не то, что вам нужно.
То, что происходит, заключается в том, что вы вызываете неопределенное поведение, нарушая Правило одного определения .
В сборках выпуска и отладки будут установлены разные флаги препроцессора, и вы обнаружите, что std::string
имеет разные определения в каждом случае. Спросите у своего компилятора, что такое sizeof(std::string)
- MSVC10 говорит мне, что это 32 в отладочной сборке и 28 в сборке выпуска (это не заполнение - 28 и 32 являются границами 4 байтов).
Так что же происходит? Переменная s
инициализируется с использованием отладочной версии конструктора копирования для копирования версии выпуска std::string
. Смещения переменных-членов в разных версиях различны, поэтому вы копируете мусор. Реализация MSVC эффективно хранит указатели начала и конца - вы скопировали в них мусор; поскольку они больше не равны нулю, деструктор пытается их освободить, и вы получаете нарушение прав доступа.
Даже если реализации кучи были бы одинаковыми, он зависал бы, так как вы освобождали указатели мусора в памяти, которая никогда не выделялась изначально.
В итоге: версии CRT должны совпадать, но должны соответствовать определениям, включая определения в стандартной библиотеке .