Просто у вас ошибка в этой строке
MyString MyString::Copy(const char *string) { }
Вы возвращаете копию объекта. Он нигде не используется:
MyString::MyString(const char *string)
{
Copy(string); // Вот здесь
}
И для этой копии вызывается деструктор.
А должно быть так:
MyString& MyString::Copy(const char *string) { }
В этом случае метод вернёт ссылку на объект.
Но тогда вам следует объявить этот метод как статичный и назвать его не "копировать", а "создать":
class MyString {
MyString(const char* string);
static MyString* Create(const char *string);
};
MyString::MyString(const char *string)
{
m_length = StrLen(string);
m_string = new char[m_length + 1];
if (m_string != nullptr) {
for (size_t i = 0; i < m_length; ++i)
m_string[i] = string[i];
m_string[m_length] = '\0';
}
}
MyString* MyString::Create(const char *string)
{
return new MyString(string);
}
Обратите внимание - мой метод возвращает указатель. Это такое правило - никогда не возвращайте по ссылке объект, который создаётся внутри функции. Иначе потом будете рефакторить весь код.
В C++ нет стандартного соглашения, как должен поступить компилятор с объектом, возвращённым из функции по ссылке. Одни компиляторы такие объекты просто тихо удаляют, другие - нет.
И вот, у вас объект в памяти есть, вы его не удаляли, и он даже доступен. Всё работает.
Но потом вы создаёте какой-то новый объект, и у вас крашится программе при попытке доступа к прошлому объекту.
Что такое? Почему компилятор сгенерил код, который затирает память? Куда подевался объект в том месте программы, в котором раньше всё работало?
Просто физически нереально отыскать место возникновения ошибки через неделю, за которую вы написали ещё 30 тысяч строк кода.
Поэтому всегда возвращайте объект из функции только по указателю.