Ответ 1
Код:
char *p = new char[200];
p[100] = '\0';
delete[] p;
отлично подходит для С++. delete не знает или не заботится о строках с нулевым завершением, поэтому ваша ошибка должна иметь какую-то другую причину.
Этот вопрос связан с этим. С учетом этого кода:
char *p = new char[200];
delete[] p;
что произойдет, если вы установите p[100] = '\0'
перед удалением p?
У меня был код, в котором у меня была ошибка отладки, когда я попытался удалить массив char с нулевым завершением, что-то об исключении неактивной памяти кучи. Казалось, что из памяти массива удаляется память.
Код:
char *p = new char[200];
p[100] = '\0';
delete[] p;
отлично подходит для С++. delete не знает или не заботится о строках с нулевым завершением, поэтому ваша ошибка должна иметь какую-то другую причину.
Ничего особенного не произойдет. Вы должны писать в каком-то месте в середине выделенной памяти (100 байт, кроме начала, 99 байт до конца выделенной памяти).
Тогда вы освободите выделенную память. Компилятор будет обрабатывать его точно так, как мы ожидали. Память, выделенная этим, полностью не связана с нулевыми завершенными строками. Вы можете вставить все, что захотите, в эту память. Это некоторая "сырая" часть хранилища, вы могли бы даже создать какой-нибудь произвольный объект С++ в этой памяти (размещение нового).
Ваша ошибка в другом месте. Например, некоторая общая ошибка - это одна, где конструктор вызывается один раз, но деструктор вызывается дважды, дважды удаляя что-то:
struct A { P *p; A() { p = new P; } ~A() { delete p; } };
A getA() { return A(); } int main() { A a = getA(); }
Теперь происходит то, что конструктор по умолчанию вызывается один раз, а созданный объект копируется ноль или более раз. Но деструктор запускается для каждой созданной копии. Таким образом, вы вызовете деструктор указателя более одного раза, что приведет к таким странным ошибкам. Правильный способ исправить это - использовать интеллектуальный указатель, например shared_ptr
. В качестве упражнения вы также можете сделать это без написания правильных конструкторов копирования, которые копируют объект и выделяют память в конструкторе копирования, так что копия и соответствующий исходный объект сохраняют разные указатели.
Я думаю, вы смешиваете простой старый массив char с массивом char, представляющим строку стиля C. Оператор delete С++ ничего не заботит для строкового массива стиля C. Все, что он когда-либо увидит, это массив символов. Это действительно ничем не отличается от того, как удалить массив int.
Наличие или отсутствие нулевого терминатора имеет значение только для функций, которые обрабатывают char*
как строку стиля C.
Это не имеет значения. delete [] следует использовать для удаления динамически распределенного массива независимо от его содержимого.
Это должно работать нормально, насколько я могу судить. Вы выделяете кусок памяти, и ОС должна следить за ней и иметь возможность освободить ее, когда ее спросят. Не имеет значения, какие значения вы вложили в выделенный буфер.
Приклеивание NULL в середине массива символов, безусловно, будет мешать функциям строки C, таким как strcmp
, strlen
и т.д., но это совсем другое дело.
Как отмечали другие, код, который вы опубликовали, абсолютно корректен и не должен вызывать никаких проблем.
Ошибка могла быть вызвана изменением значения p
где-то посередине.