Глава 6. Базовые типы данных и операции__________________________743
Динамическое размещение массива объектов. Размещение массива объектов в куче синтаксически немного отличается. Массив — это область памяти, подряд заполненная объектами одного типа. Указатель адресует первый (точнее — нулевой) элемент массива, и этот элемент доступен простым разыменованием указателя, или как элемент массива с индексом 0:
int *p = new int [5];
*р = 1; // разыменование указателя р[0] "• 1; //' тот же элемент массива
Все остальные элементы располагаются по следующим индексам, что то же самое, что и разыменование суммы указателя и индекса. То есть второй объект имеет индекс 1 и может быть представлен как
*(р+1) = 2;
ИЛИ Р[1] ° 2;
С точки зрения нотации предпочтительнее операция массива ([ ]).
Этот пример демонстрирует размещение массива целых чисел. Для произвольного массива разница будет заключаться только в задании соответствующего типа данных и нужного размера. Чтобы, например, выделить память под массив из ста вещественных чисел, надо написать
float *pfloat = new float[100];
Операция delete. Самое важное правило, касающееся операций new и delete, состоит в том, что если вы не освободите захваченную память, то система сама не сможет ее забрать обратно. Для освобождения памяти предусмотрена операция delete (она тоже выглядит как операция, но транслируется в вызов функции). Каждому выделению памяти при помощи new должен соответствовать вызов delete, в противном случае, как вы увидите далее, результат будет плачевным.
Формы операции delete. Форма вызова операции delete должна соответствовать форме вызова соответствующей операции new. Это означает, что если в вызове new имела место операция массива [], то она должна также присутствовать при вызове delete. Если вы создавали единичный объект, а не массив, то в вызове delete не следует применять операцию массива.
Например, для размещения и уничтожения единичного целого следует написать
int *p = new int; // вызов new • delete p; // правильный вызов delete