С++ для начинающих




Динамическое выделение памяти и указатели - часть 3


Вторая форма оператора new выделяет память под массив заданного размера, состоящий из элементов определенного типа:

int *pia = new int[4];

В этом примере память выделяется под массив из четырех элементов типа int. К сожалению, данная форма оператора new не позволяет инициализировать элементы массива.

Некоторую путаницу вносит то, что обе формы оператора new возвращают одинаковый указатель, в нашем примере это указатель на целое. И pint, и pia объявлены совершенно одинаково, однако pint указывает на единственный объект типа int, а pia – на первый элемент массива из четырех объектов типа int.

Когда динамический объект больше не нужен, мы должны явным образом освободить отведенную под него память. Это делается с помощью оператора delete, имеющего, как и new, две формы – для единичного объекта и для массива:

// освобождение единичного объекта

delete pint;

// освобождение массива

delete[] pia;

Что случится, если мы забудем освободить выделенную память? Память будет расходоваться впустую, она окажется неиспользуемой, однако возвратить ее системе нельзя, поскольку у нас нет указателя на нее. Такое явление получило специальное название утечка памяти. В конце концов программа аварийно завершится из-за нехватки памяти (если, конечно, она будет работать достаточно долго). Небольшая утечка трудно поддается обнаружению, но существуют утилиты, помогающие это сделать.

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

Упражнение 2.3

Объясните разницу между четырьмя объектами:

(a) int ival = 1024;

(b) int *pi = &ival;

(c) int *pi2 = new int(1024);

(d) int *pi3 = new int[1024];

Упражнение 2.4

Что делает следующий фрагмент кода? В чем состоит логическая ошибка? (Отметим, что операция взятия индекса ([]) правильно применена к указателю pia. Объяснение этому факту можно найти в разделе 3.9.2.)

int *pi = new int(10);

int *pia = new int[10];

while ( *pi < 10 ) {

  pia[*pi] = *pi;

  *pi = *pi + 1;

}

delete pi;

delete[] pia;




Содержание  Назад  Вперед