8.3.2. Динамическое распределение памяти
В компиляторе С для эффективного управления динамической памятью используются указатели. Они позволяют объявить большое число переменных различных типов и размеров. Когда память динамически распределена для переменных в RAM, указатель может привести вас к ресурсам памяти для переменной.
Динамическое распределение памяти осуществляется с помощью команды распределения памяти malloc
. Эта команда содержится в файле заголовка stdlib.h, который является частью любого С компилятора. Команда malloc
обычно используется вместе с функцией sizeof
. Эта комбинация функций чрезвычайно полезна при динамическом распределении памяти. Общая форма этой комбинации функций:
Ptr = (variable_type)*malloc(sizeof(variable_type));
Большинство структур данных объявляется и распределяется с помощью этой методики. Когда переменная больше не нужна, пространство памяти используемое для нее, возвращается системе с помощью функции free
. Это наилучший способ динамического распределения памяти. Мы создаем переменные на ходу (в процессе выполнения программы), когда мы нуждаемся в них, и избавляемся от переменных, когда они больше не нужны.
При таком распределении и освобождении памяти, происходящем в процессе выполнения программы, необходима эффективная система управления памятью. Динамическая память — это часть памяти RAM, используемая для динамического распределения памяти. Как мы упомянули прежде, важно сохранять стек и динамическую память, отделенными от друг друга.
Теперь, когда мы имеем два отдельных пространства RAM в нашей карте памяти, мы можем легко выделить одну из них для стека, а другую — для динамической памяти. Мы рекомендуем использование меньшего пространства для стека и большего для динамической памяти. В данном компиляторе имеются параметры настройки, конфигурируемые пользователем и позволяющие установить адрес начала для стека и области динамической памяти.
Получив способ динамического распределения памяти, мы можем теперь создавать структуры данных для использования в наших ОСРВ. В следующем разделе мы проведем общий обзор структур данных, используемых в ОСРВ: структур (или записей), списков с указателями, очередей, и круговых очередей. Как только мы познакомимся с каждым из этих основных типов, мы сможем объединять их в более сложные структуры данных, используемые для работы ОСРВ.
8.3.3. Структуры данных
В этом разделе мы проведем общий обзор структур данных, используемых в операционных системах, работающих в режиме реального времени. Мы выполним обзор каждой структуры данных отдельно и затем объединим их, чтобы выполнять различные операции внутри ОСРВ.
Рис. 8.4. Запись для автомобиля. Запись содержит поля данных, совокупность которых описывает автомобиль
Каждый из типов данных в записи называется полем. Мы объявляем запись или структуру, используя следующий синтаксис:
struct car {
int year; /* год производства* /
char make[10]; /*BWM, Hummer, Saturn */
char model[12]; /*купе, обратимый, SUV, пикап */
char VIN[10]; /* комбинация цифр, букв */
float mileage; /*показания счетчика: от 0 до 500,000+ */
struct car *next; /*указатель на следующий автомобиль в списке*/
};
/*typedef обеспечивает компилятор an alternate???*/
typedef struct car ELEMENT; /*для типа переменной */
typedef ELEMENT *car_temp_ptr; /*определяет указатель на автомобиль*/
Как можно видеть, все поля записи описывают различные параметры данного автомобиля. Мы привели сокращенный список параметров. Структура может содержать столько полей, сколько необходимо. Мы выбрали для каждого поля тот тип данных, который наиболее подходит для описания каждого параметра автомобиля.