Вышеуказанное не просто приводит к утечке памяти; это вызывает неопределенное поведение , что намного, намного хуже.
Проблема в трех последних строках:
str2 = str1;
delete [] str2;
delete [] str1;
Если мы игнорируем эту первую строку, то последние две строки правильно восстанавливают всю память, выделенную в этой функции. Однако в этой первой строке str2
указывает на тот же буфер, что и str1
. Поскольку str2
является единственным указателем в программе на динамическую память, на которую она ссылается, эта строка пропускает память для этого буфера. Хуже того, когда вы затем выполняете следующие две строки для очистки двух указателей, вы удаляете один и тот же блок памяти дважды, один раз через str2
и один раз до str1
. Это приводит к неопределенному поведению и часто вызывает сбои. Особо злонамеренные пользователи могут фактически использовать это для выполнения произвольного кода в вашей программе, поэтому будьте осторожны, чтобы не делать этого!
Но здесь нужно учитывать одну проблему более высокого уровня. Вся проблема с этой настройкой состоит в том, что вы должны делать все свое собственное управление памятью. Если вы решите использовать std::string
вместо необработанных строк в стиле C, то вы можете написать код следующим образом:
string str1 = "Memory leak"; // Actually, it doesn't. :-)
string str2;
str2 = str1; // Okay, make str2 a copy of str1
// All memory reclaimed when this function or block ends
Теперь нет необходимости явно управлять памятью, и вам не нужно беспокоиться о переполнении буфера или двойном освобождении. Вы спасены волшебством выделения памяти объекта.