Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Задачи по ООП для 234 группы (окончание).doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
300.54 Кб
Скачать

3.3. Операции new и delete

Я тебя породил, я тебя и убью!

Н.В.Гоголь. Тарас Бульба

Операции:

<указатель> = new <имя типа>

либо

<указатель> = new <имя типа>( <инициализатор>)

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

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

  • операция new float выделяет участок памяти размером 4 байта;

  • операция new int(l5) выделяет участок памяти в 2 байта и инициа­лизирует этот участок целым значением 15.

Напомним, что определение указателя имеет вид: тип *<имя указателя>; . Имя указателя - это идентификатор. Таким образом, int *h; - определение указателя h, который может быть связан с участком памяти, выделенным для ве­личины целого типа. Введя с помощью определения указатель, можно присвоить ему возвращаемое операцией new значение:

h = new int(15); .

В дальнейшем доступ к выделенному участку памяти обеспечивает выражение *h.

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

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

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

delete <указатель>; , где

указатель адресует освобождаемый участок памяти, ранее выделенный с помощью операции new. Например: delete h; освободит участок па­мяти, связанный с указателем h. Повторное применение операции delete к тому же указателю дает неопределенный результат.

Для освобождения памяти, выделенной для массива, используется следующая модификация того же оператора: delete[ ] <указатель>;, где указатель связан с выделенным для массива участком памяти.

3.4. Демонстрационные примеры Чтение и переработка являются ключевыми в программировании. Б.Керниган, ф.Плоджер

Приведем несколько примеров, иллюстрирующих применение указателей.

Пример 1. Инициализация вещественного "массива" размерностью 32000 элементов.

#include<iostream.h>

void main ()

{

// float x[32000]; Наличие этого описания приведет к ...

//Выделение места для массива и размещение адреса начала

//массива в переменной g.

float *g=new float [32000];

for (int i=0; i<32000; i++)

{ *(g+i) = i;

cout<<*(g+i)<<" ";

}

delete[] g;//Возврат памяти в "кучу".

}

Пример 2. Использование указателей для работы со списками.

Создадим сначала две динамические переменные:

R = new CT; Q = new CT;

А теперь построим список, содержащий два звена:

(*R).I = 15; (*Q).I = 20;

(*R).P = Q;

(*Q).P = NULL;

Результат:

Создадим еще один список: R1 = new CT; Q1 = new CT;

(*R1).I = 13;

( *Q1).I = 53;

(*R1).P = Q1;

(*Q1).P = NULL;

Р езультат:

Проиллюстрируем теперь схематически результат действия опера­тора присваивания:

(*R1).P = (*R).P;

#include<iostream.h>

typedef struct ct *POINTER; // Рекурсивная структура

typedef struct ct //данных.

{

int I;

POINTER P;

} CT;

POINTER R,Q,R1,Q1;

void main ()

{ // Создание первого списка.

R = new CT;

Q = new CT;

(*R).I = 15; (*Q).I = 20; (*R).P = Q; (*Q).P = NULL;

cout<<"Информационное поле второго звена списка: "

<<(*(*R).P).I<<endl;

// Создание второго списка.

R1 = new CT;

Q1 = new CT;

(*R1).I = 13; (*Q1).I = 53; (*R1).P = Q1; (*Q1).P = NULL;

cout<<"Информационное поле второго звена списка: "

<<(*(*R1).P).I<<endl;

// Работа со списками.

(*R1).P = (*R).P;

cout<<(*(*R1).P).I<<endl;

}