2016-08-06 8 views
0

Может ли кто-нибудь объяснить, почему этот код приводит к повреждению кучи?Удаление указателя вызывает повреждение кучи

string someText = "hello hello"; 
char **arrayOfCharPtr = new char*[5]; 
arrayOfCharPtr[0] = new char[someText.length()]; 
strcpy(arrayOfCharPtr[0], someText.c_str()); 
delete[] arrayOfCharPtr[0]; 

Большое спасибо!

+1

Ваш массив - один символ короткий, нет места для нулевого символа, скопированного 'strcpy'. – user657267

+0

Ok, length() + 1. Но почему это вызывает утечку памяти? сама строка strcpy не вызывает ошибку; это строка удаления, которая ее вызывает. Почему он не может просто удалить все, что находится в arrayOfCharPtr [0], независимо от того, как долго его содержимое? – Johan

+1

«Строка strcpy сама по себе не вызывает ошибки». Добро пожаловать в неопределенное поведение, где все может показаться работающим, но затем взорваться пугающими путями вдали от источника. – user657267

ответ

3

Вам необходимо выделить один символ больше длины вашей строки для сохранения последнего символа '\ 0'.

arrayOfCharPtr[0] = new char[someText.length()+1]; 

В вашем случае зЬгсру запишет последний «\ 0» после выделенного блока, и это портит кучу.

Инструменты, такие как valgrind, могут помочь разобраться. valgrind выводит сообщение об ошибке

==16970== Invalid write of size 1 
==16970== at 0x4C3106F: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==16970== by 0x400C47: main 
==16970== Address 0x5ab5cfb is 0 bytes after a block of size 11 alloc'd 
==16970== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==16970== by 0x400C1C: main 

, который локализует источник ошибки.