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

Лекция 9

Динамическое распределение памяти в языке С++

Различают статическое и динамическое распределение памяти компьютера под объекты.

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

Например, определение переменной int array[10]; свидетельствует о том, что в программе вводится массив, который требует память для размещения десяти элементов целого типа. Компилятор каждому имени объекта ставит в соответствие адрес. В связи с этим, доступ к статическим объектам реализуется по именам.

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

Каждой программе компьютер выделяет память, состоящую из четырех секций:

  1. программная секция, включающая код программы;

  2. секция данных, содержащая внутренние представления статических объектов;

  3. стек – область памяти, используемая при реализации функций;

  4. динамическая память (ДП), предоставляемая программе при ее выполнении.

Создание динамического объекта осуществляется в два этапа

1 этап. Резервирование места в ДП под объект и формирование значения указателя, ссылающегося на это объект.

2 этап. Запись значения объекта в ДП по указанному адресу.

Для выделения ДП под объект служит оператор new.

Синтаксис этого оператора:

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

Оператор new выделяет в ДП место под значение заданного типа и возвращает адрес этой области. Например:

float *p;

p=new float;

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

*p=15.46;

Для освобождения ДП используется оператор delete:

delete <имя указателя>;

Оператор delete освобождает память, ранее связанную с указателем. Например:

delete p;

В операторе delete необходимо использовать только тот указатель, который был определен в операторе new.

При использовании оператора new можно инициализировать значение объекта:

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

Здесь тип инициализатора должен быть совместимым с типом объекта, для которого выделяется память.

Например:

void main()

{ int *p;

p=new int(250);

cout<< *p<<”\n”;

delete p;

}

С помощью оператора new можно выделять память под массивы:

<имя указателя>= new <тип элемента массива>[<размер>];

Здесь <размер>- количество элементов в массиве.

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

delete []<имя указателя>;

Пример. Создать в ДП массив из 10 целых чисел, вывести его на экран и освободить ДП.

void main()

{ int *p, i;

p=new int[10];

for( i=0; i<10; i++)

p[i]=i;

for( i=0; i<10; i++)

cout<< p[i]<<” “;

cout<<”\n”;

delete[] p;

}

Используя операторы new и delete можно выделять ДП под экземпляры классов и освобождать ее.

При размещении объекта в ДП с помощью оператора new вызывается конструктор, а при освобождении ДП вызывается деструктор.

Пример. Разместить объект класса “прямоугольник” в ДП, вычислить площадь прямоугольника и освободить ДП.

#include <iostream.h>

class Rectangle

{ int width, height;

public:

Rectangle(int w, int h)//конструктор

{width=w; height=h;

cout<<”Создание прямоугольника.\n”;

}

~ Rectangle()//деструктор

{cout<<”Разрушение прямоугольника.\n”;

}

int area()

{return width * height;

}

};

void main()

{ Rectangle *p;

p= new Rectangle(10,8);

cout<<”Площадь=”<<p->area()<<”.\n”;

delete p;//вызов деструктора

}

Результат:

Cоздание прямоугольника.

Площадь=80.

Разрушение прямоугольника.

Динамические структуры данных

ДП широко используется для хранения динамических структур данных (ДСД). К ДСД относят списки, стеки, очереди и деревья.

Рассмотрим списки. Различают линейные и циклические, однонаправленные и двунаправленные, упорядоченные и неупорядоченные списки.

Линейный однонаправленный список (ЛОС)

ЛОС – это ДСД, каждый элемент которой включает информационное поле и указатель на следующий элемент. Поле указателя последнего элемента ЛОС имеет значение NULL (пустой указатель). Информационное поле содержит ключ, идентифицирующий элемент, и ,возможно любую другую информацию.

На языке С++ элемент ЛОС можно описать в виде класса.

Например:

class list

{public:

char name[80];//имя

int year;//год рождения

list *next;//указатель на следующий элемент списка

void create();//создание списка

void output();//вывод на экран элементов списка

};