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

Модели памяти.

Существует несколько видов моделей памяти: 1) малая модель; 2) средняя модель; 3) компактная модель; 4) большая модель; 5) максимальная модель.

В малой (small) модели памяти программа занимает два стандартных сегмента: сегмент кода и сегмент данных, в котором размещен также стек. Малая модель подходит для большинства программ и потому назначается компилятором по умолчанию.

В средней (medium) модели памяти для данных и стека программы выделяется один сегмент, а для кода — столько сегментов, сколько потребуется. Каждому исходному модулю программы выделяется собственный сегмент кода.

В компактной (compact) модели программному коду выделяется только один сегмент, а данным — столько сегментов, сколько потребуется. Компактная модель применяется для программ, небольших по количеству операторов, но работающих с большим объемом данных.

В большой (large) модели и под код, и под данные выделяется несколько сегментов. Большая модель используется для больших программ с большим объемом данных.

Максимальная (huge) модель аналогична большой модели, за исключением того, что в ней снимается ограничение на размер массивов.

Статические и динамические данные.

Статические данные — это все данные, объявленные в программе с классом памяти extern или static. Формальные параметры функций и локальные переменные функций и блоков не являются статическими данными. Они хранятся не в сегменте данных, а в сегменте стека. Он обычно совмещен со стандартным сегментом данных физически.

Динамические данные – это данные, внутреннее строение которых формируется по какому-либо закону, но количество элементов, их взаиморасположение и взаимосвязи могут динамически изменяться во время выполнения программы, согласно закону формирования.

Функции, поддерживающие основные операции с динамической памятью.

Динамически распределяемую память следует использовать в случае если мы заранее (на момент написания программы) не знаем сколько памяти нам понадобится и при работе с большими объемами данных.

Для работы с динамической памятью в языке С++ используются следующие функции: malloc, calloc, free, realloc.

Функция malloc, входным параметром которой является размер требуемой области динамической памяти в байтах, а выходным – значение типа void *, указывающее на первый байт выделенной области (void *malloc(size_t size)). Например, для выделения памяти под 1 000 000 int`ов необходимо выполнить следующий код:

int * p = (int *) malloc(1000000*sizeof(int));

Если ОС не смогла выделить память, то malloc возвращает 0.

Функция free. После окончания работы с выделенной динамически памятью нужно освободить ее. Для этой цели используется функция free, которая возвращает память под управление ОС. В качестве входного параметра в free нужно передать указатель, значение которого полученно из функции malloc.

Функция calloc. Функция работает аналогично malloc, но отличается синтаксисом (вместо размера выделяемой памяти нужно задать количество элементов и размер одного элемента) и тем, что выделенная память будет обнулена. Например, после выполнения

int * q = (int *) calloc(1000000, sizeof(int));

q будет указывать на начало массива из миллиона int`ов инициализированных нулями.

Функция realloc. Функция изменяет размер выделенной памяти. Если размер указанный в параметре size больше, чем тот, который был выделен под указатель ptr, то проверяется, есть ли возможность выделить недостающие ячейки памяти подряд с уже выделенными.

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

В С++ есть свой механизм выделения и освобождения памяти — это операторы new и delete.

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

тип данных *имя_указателя = new тип_данных(значение).

Пример использования new:

int * p = new int[1000000]; // выделение памяти под 1000000 int`ов

Т.е. при использовании функции new не нужно приводить указатель и не нужно использовать sizeof().

Освобождение выделенной при помощи new памяти осуществляется посредством следующего вызова:

delete [] p;

Если требуется выделить память под один элемент, то можно использовать:

int * q = new int;

или

int * q = new int(10); // выделенный int проинциализируется значением 10

в этом случае удаление будет выглядеть следующим образом:

delete q;

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

Динамические структуры данных – это структуры данных, память под которые выделяется и освобождается по мере необходимости.

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

struct Node{ Data d; // тип данных Data должен быть определен ранее Node *р; };

Наши рекомендации