На первый взгляд, все в полном порядке – использованию new соответствует применение delete, но кое-что здесь совершенно неверно. Поведение программы непредсказуемо. По меньшей мере, 99 из 100 объектов string, на которые указывает stringArray, вероятно, не будут корректно уничтожены, потому что их деструкторы, скорее всего, так и не вызваны.
При использовании
В действительности вопрос гораздо проще: является ли удаляемый указатель указателем на один объект или на массив объектов? Это критичный вопрос, поскольку схема распределения памяти для отдельных объектов существенно отличается от схемы выделения памяти для массивов. В частности, при выделении памяти для массива обычно запоминается его размер, чтобы оператор delete знал, сколько деструкторов вызывать. В памяти, выделенной для отдельного объекта, такая информация не хранится. Различные схемы распределения памяти изображены на рисунке ниже (n – размер массива):
Конечно, это только пример. От компилятора не требуется реализовывать схему именно таким образом, хотя многие так и делают.
Когда вы используете оператор delete для указателя, как он может узнать, что где-то имеется информация о размере массива? Только от вас. Если после delete стоят квадратные скобки, то предполагается, что указатель указывает на массив. В противном случае компилятор считает, что это указатель на отдельный объект:std::string *stringPtr1 = new std::string;
std::string *stringPtr2 = new std::string[100];
…
delete stringPtr1;
delete[]stringPtr2;