а для массива

int *r = new int[10]; // массив целых чисел delete [] г; // уничтожение массива целых

Хотя при размещении массива задается его размер, при удалении массива его указывать не нужно; он запоминается и управляется без постороннего вмешательства. Считайте new и delete умной и согласованной парой оператор-функций.

Применительно ко второму примеру вызов

delete r;

означает в точности то же самое, что

delete r[0] ;

В обоих случаях происходит удаление только первого элемента массива, в то время как вам, скорее всего, нужно уничтожать массив целиком.

*

Как избежать утечек памяти. Помните, выше шла речь о том, что области памяти, не адресуемые никаким указателем, скорее всего будут потеряны при выходе из функции или изменении области видимости. Каждая область видимости обычно определяется парой фигурных скобок, вроде тех, что открывают и закрывают определение функции.

Рассмотрим пример:

void Foo() { // Начало области видимости Foo

int *p = new int[10];

// операторы тела функции } // конец области видимости Foo

// ой, а мы забыли вызвать delete

В этом примере пропущен вызов delete. После завершения работы функции стек будет очищен и указатель на целое р будет потерян. Вместе с переменной р теряется только указатель на массив целых чисел, но сам массив при этом память не освобождает. Возникновение таких осиротевших блоков памяти называется проблемой утечки (slicing problem), а сами блоки — утечками (leaks).

В действительности плохо даже не столько то, что потеряно десять целых чисел, сколько то, что они будут теряться вновь и вновь при каждом вызове этой функции. Утечки памяти проявляют себя по-разному. По ходу дела мы постараемся разобраться со всеми проявлениями ошибок подобного рода.

Реализация операций neW и delete

Оглядываясь назад можно заметить, что через всю историю языков программирования красной нитью проходит тема укрупнения и развития. Во