Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛекцииЛаб(Часть_1_Книги).doc
Скачиваний:
7
Добавлен:
03.05.2019
Размер:
1.04 Mб
Скачать

§4. Распределение динамической памяти.

4.1. Операция new

Использование операции new является одним из способов, как определить значение переменной указателя (другие способы смотри в §2). В простейшем случае синтаксис применения этой операции такой:

указатель=new имя_типа;

Например, пусть объявлена переменная-указатель float *p;. Тогда операция

p=new float;

выделяет и делает доступным свободный участок динамической памяти, размер которого соответствует типу данных, определяемому именем типа. В нашем примере резервируется память размером 4 байта для размещения одного вещественного числа. Кроме этого, в случае успешного выполнения операция new возвращает адрес начала выделенного участка. Значение этого адреса присваивается переменной- указателю (в примере переменной p). Но значение выделенной ячейки, которое в программе обозначается *p, после выполнения этой операции ещё не определено. Поэтому cout<<(*p) выведет случайное число. Для задания значения *p надо выполнить, например, ввод ( cin >> (*p);), или использовать другой способ ( присваивание, получение с помощью функции и т.п..). Напомним, что cin>>p; приводит к ошибке.

Если участок нужных размеров не может быть “найден”, то операция new возвращает нулевое (точнее, неопределённое) значение адреса, которое в программе обозначается константой NULL, которая записывается обязательно большими буквами. Тогда в программе можно записать

if (p==NULL) { cout<<”\nError”; exit(0);}

Как нулевое числовое значение, так для указателей значение NULL равносильно false в операциях сравнения. Поэтому последнее условие в if равносильно

if (!p) {cout<<”\nError”; exit(0);}

С помощью рассматриваемой операции new можно проинициализировать не только значение указателя, но и задать значение выделенной ячейки памяти. В таком случае операция применяется так:

указатель=new имя_типа(значение);

Например,

p=new float(4.1);

определяет как значение указателя p, так и значение *p. Это равносильно

p=new float; *p=4.1;

Заметим, что значение записывается в круглых, а не в квадратных скобках. Последние будем позже использовать для создания динамического массива. Но динамический массив так инициализировать нельзя! (см.глава 2).

Доступ к переменной, адрес которой находится в p, как и раньше, осуществляется с помощью той же операции “*” (разыменование). Поэтому

cout<<p<<” “ <<(*p);

выведет адрес в 16-й системе счисления и число 4.1.

4.2. Операция delete

Операция используется для явного освобождения выделенного операцией new участка памяти. В нашем случае её синтаксис такой: delete указатель;. Для примера (см. 4.1) delete p; освобождает ячейку, адрес которой хранился в переменной- указателе (p). Но при этом ячейка p, в которой находится адрес вещественного числа, из памяти не удаляется. В дальнейшем её можно использовать. Но значение как p, а, значит, и *p после выполнения операции не определено.

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

float x; float *q=&x;

то результат операции delete q; непредсказуем. Нельзя использовать эту операцию и для статического массива. Следующий код

const n=10; int a[n]; … delete a;

приводит к ошибке.