Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
информатика.doc
Скачиваний:
76
Добавлен:
09.02.2015
Размер:
450.05 Кб
Скачать

Динамическое распределение памяти

Создание и использование динамических структур данных требует дина­мического распределения памяти - возможности получать в процессе испол­нения дополнительную память для хранения новых узлов и освобождать бло­ки памяти, ставшие ненужными. Максимальный размер выделяемой динами­чески памяти определяется доступной физической памятью компьютера или доступным виртуальным адресным пространством в системе с виртуальной па­мятью. Однако часто эти размеры значительно меньше, потому что память разделяется между многими пользователями (задачами).

Для динамического распределения памяти необходимо применение функ­ций malloc и free, а также операции sizeof. Функция malloc принимает в ка­честве аргумента число байт, которое необходимо выделить, и возвращает ука­затель на выделенную память типа void*. Указатель void* можно присвоить любой переменной-указателю. Функция malloc обычно используется совмест­но с операцией sizeof. Например, оператор

newPtr = malloc(sizeof(struct node));

оценивает sizeof(struct node) для определения размера в байтах структуры типа struct node, выделяет новый блок памяти размером в sizeof(struct node) байт, и сохраняет указатель на выделенную память в переменной newPtr. Если необходимого количества памяти нет в наличии, malloc возвращает указатель NULL.

Функция free освобождает память, т.е. память возвращается системе, и в дальнейшем ее можно выделить снова. Для высвобождения памяти, динами­чески выделенной предыдущим вызовом оператора malloc, используется опе­ратор

free(newPtr);

Связанные списки

Связанный список - это линейный набор ссылающихся на себя структур, называемых узлами, и объединенных указателем-связкой, отсюда и назва­ние - «связанный» список. Доступ к связанному списку обеспечивается ука­зателем на первый узел списка. Доступ к следующим узлам производится че­рез связывающий указатель, хранящийся в каждом узле. По общему соглаше­нию связывающий указатель в последнем узле списка устанавливается в NULL, отмечая конец списка. Данные хранятся в связанном списке динами­чески - каждый узел создается по мере необходимости. Узел может содер­жать данные любого типа, включая другие структуры. Стеки и очереди также принадлежат к линейным структурам данных, и, как мы увидим, являются специальными вариантами связанных списков. Деревья же являются нели­нейными структурами данных.

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

Стеки

Стек - это упрощенный вариант связанного списка. Новые узлы могут добавляться в стек и удаляться из стека только сверху. По этой причине, стек часто называют структурой вида последним пришел - первым вышел (LIFO). На стек ссылаются через указатель на верхний элемент стека. Связывающий элемент в последнем узле стека установлен равным NULL, чтобы пометить границу стека.

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

Основные функции, используемые при работе со стеками - push и pop. Функция push создает новый узел и помещает его на вершину стека. Функция pop удаляет верхний узел стека, освобождает память, которая была выделена изъятому узлу, и возвращает изъятое значение.

Стеки имеют множество разнообразных применений. Например, всякий раз, когда происходит вызов функции, вызванная функция должна знать, как вернуться к вызывающей, поэтому адрес возврата помещается в стек. В слу­чае, когда происходит целый ряд последовательных вызовов, адреса возврата размещаются в стеке в порядке последним пришел - первым вышел, так что после завершения выполнения каждой функции происходит переход к функ­ции, ее вызывавшей.