Лекция 10. Модульное программирование: динамические данные.
Модели памяти. Статические и динамические данные. Механизмы выделения, перераспределения и очистки динамической памяти. Функции, поддерживающие основные операции с динамической памятью. Операторы new и delete. Динамические структуры данных. Линейные списки, стеки, очереди, бинарные деревья.
Десятая лекция курса «Программирование» посвящена знакомству с динамическими данными, динамической памятью и операциями с ней. В данной лекции приводятся определения ключевых понятий и общие сведения.
Модели памяти.
Существует несколько видов моделей памяти: 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, то проверяется, есть ли возможность выделить недостающие ячейки памяти подряд с уже выделенными.
