Играя с массивом символов - PullRequest
1 голос
/ 25 марта 2012

Безопасно ли делать что-то вроде этого:

char* charArray = new char[10];  
strcat(charArray, "qwertyuiop");  
charArray[3] = '\0';  
delete [] charArray;

Будет ли все удалено? Или то, что после \0 не будет? Я не знаю, оставляю ли я мусор.

РЕДАКТИРОВАТЬ: должно быть strcpy

Ответы [ 5 ]

7 голосов
/ 25 марта 2012

Помимо того, что new[] для POD-типов не инициализирует массив нулем, а strcat записывает завершающий '\0' после конца выделенной области, все выглядит хорошо: в частности, delete удалит весь блок.

Причина записи после конца выделенного блока состоит в том, что для 10-символьной строки "qwertyuiop" требуется 11 байтов для хранения.

5 голосов
/ 25 марта 2012

Если вы хотите написать strcpy вместо strcat, тогда это безопасно и правильно. Но, похоже, у вас неправильное представление о delete [] charArray. Он не удаляет символы, он удаляет память, указанную charArray. Память даже после delete [] charArray может содержать эти символы, хотя это не гарантируется.

Однако, если вы действительно хотели написать strcat, и это не опечатка, тогда ваш код вызывает неопределенное поведение, поскольку charArray содержит мусор, к которому strcat попытается объединить вторая строка.

3 голосов
/ 25 марта 2012

delete[] освобождает память, выделенную после уничтожения объектов внутри (что ничего не делает для char). Его не волнует контент, т. Е. Он освободит столько объектов, сколько было выделено.

Обратите внимание, что использование strcat() зависит от нулевого символа для поиска конца строки и что память, возвращаемая из new char[n], неинициализирована. Вы хотите начать с

*charArray = 0;

... и вы можете рассмотреть strncat() или, что еще лучше, вообще не использовать это, а использовать std::string.

2 голосов
/ 25 марта 2012

Оператор delete[] ничего не знает о том, что хранится в буфере (включая строку или нет), поэтому он удалит все 10 символов. Однако ваш strcat вызов переполняет конец массива (поскольку строки C имеют нулевой байт в качестве терминатора), что может нарушить удаление на вашей платформе и в целом небезопасно.

2 голосов
/ 25 марта 2012

Нет, все в порядке, весь массив удален. delete не смотрит на то, на что указывает указатель. Пока вы сопоставляете new с delete и new[] с delete[], необходимый объем памяти будет освобожден.

(Но рассмотрите возможность использования std::string вместо массивов символов, это позволит избежать многих ошибок, подобных той, что у вас там записывается после конца вашего массива.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...