Глава 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