Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по С++ глава 2.doc
Скачиваний:
6
Добавлен:
05.11.2018
Размер:
249.86 Кб
Скачать

2.3.10. Операторы new и delete

Операторы языка C++ new и delete используются для выделения и освобождения блоков памяти. Область памяти, в которой размещаются эти блоки, известна как свободная память. Оператор new описывает типы данных. Затем выделяется блок памяти достаточной длины для размещения объекта описанного типа, и адрес блока возвращается как указатель на заданный тип данных. Блок памяти можно выделить для хранения объекта встроенного типа, например char, int или double, например:

char *PChar; //объявление указателя

int *PInt;

double *PDouble;

PChar = new char; //размещение объекта в памяти

Pint = new int;

PDouble = new double;

*PChar = 'а'; //присваивание значения

*PInt = 5;

*PDouble = 2.25;

Оператор new чаще всего используется для размещения в памяти данных определенных пользователем типов, например, структур:

struct Node

{

char *Name;

int Value;

Node *Next;

};

// ...

Node *PNode; // объявить указатель

PNode = new Node; // разместить в памяти

PNode->Name = "hello"; // присвоить значение

PNode->Value = 1;

PNode->Next = 0;

Если выделить требуемый объем памяти окажется невозможным, то будет возвращено значение 0. Следовательно, необходимо проверять указатель перед его использованием.

PNode = new Node;

if (PNode == 0)

// условие обработки ошибки ...

else

// использование PNode ...

Если блок памяти, выделенный оператором new, больше не используется, то его можно освободить с помощью оператора delete с указателем, содержащим адрес блока. Например, следующие операторы освобождают блоки памяти, выде­ленные в предыдущем примере:

delete PChar;

delete Pint;

delete PDouble;

delete PNode;

Совет

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

Операторы new и delete полезны для динамического создания объектов в памяти, особенно когда число или размер объектов неизвестны при компиляции. Кроме того, в отличие от глобального или локального объекта, можно точно управлять периодом жизни объекта, созданного оператором new. Глобально определенный объект остается в памяти на протяжении всего времени исполнения программы. Локально определенный объект существует, пока управление программы остается в блоке, в котором он определен. Объект же, созданный оператором new, может быть помещен в любую точку программы и освобожден в любой точке программы с использованием оператора delete.

Операторы new и delete обычно удобней традиционных семейств функций распределения памяти malloc, предоставляемых библиотекой времени выполнения. В отличие от malloc, операция new автоматически определяет правильный размер объекта и возвращает указатель корректного типа. Как вы увидите в следующей главе, при использовании оператора new для объектов типа класс, автоматически вызывается конструктор класса (т.е. функция, инициализирующая его). При использовании оператора delete автоматически вызывается деструктор класса (если он был определен).

Примечание

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

Выделение памяти массивам оператором new

При выделении памяти для размещения массивов с помощью оператора new задается базовый тип данных (т.е. тип данных элементов массива) и число элементов, указываемое внутри квадратных скобок "[]", например:

void Func (int Size)

{

char *String = new char [25]; //массив из 25 символов

int *ArrayInt = new int [Size]; //массив из 'Size' целых

double *ArrayDouble;

ArrayDouble = new double [32]; //массив из 32 двойной точности

// ...

}

При выделении памяти для размещения массива, оператор new возвращает адрес первого элемента массива. Обратите внимание: здесь можно указать число элементов массива, используя переменную, что было недопустимо в объявлении переменной массива.

Чтобы освободить массив, к оператору delete при вызове требуется добавить пару квадратных скобок "[]", обозначающих, что освобождается массив, а не единичный объект базового типа. Например, следующие операторы освобождают массивы, размещенные в предыдущем примере:

delete [] String;

delete [] Arraylnt;

delete [] ArrayDouble;

Инициализация выделенной памяти

Блок памяти, выделенный с помощью оператора new, не может быть инициализирован автоматически значениями 0. Однако при использовании оператора new для выделения памяти объекту встроенного типа (например, char) можно явно инициализировать объект константой соответствующего типа, используя следующий синтаксис:

char *PChar = new char ('a'); // инициализирует char значением 'а'

int *PInt = new int (3); // инициализирует int значением 3

Объект определенного пользователем типа (например, структура) можно также инициализировать существующим объектом этого типа.

struct Node

{

char *String;

int Value;

Node *Next;

};

void Func ()

{

Node NodeA = {"hello", 1, 0};

Node *PNode = new Node (NodeA);

}

Содержимое NodeA будет скопировано поле за полем в новый объект, память для которого выделена оператором new.