Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Летняя практика КОНСПЕКТ ПО ТМиЯП.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
8.35 Mб
Скачать

Лекция №14 «Управление памятью»

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

Любая программа при загрузке для выполнения имеет определённое распределение областей памяти. Например, выделяется область программного кода, расположенная рядом со стеком, область стека обычно

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

В памяти статических переменных помещаются чаще всего глобальные переменные фиксированного размера.

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

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

Функция void*malloc(size_t size) выделяет непрерывный участок памяти длинной size байт, если такого участка выделить не удается, функция возвращает null. Получив отказ в памяти, функция может в частности из-за

фрагментированности памяти. Фрагментированность – это наличие чередующихся участков занятых и свободных в памяти. Несмотря на наличие суммарного достаточного объема свободной памяти, запрос не удовлетворяется, поскольку требуемый фрагмент должен быть непрерывным.

Void*Calloc(size_tn, size_t size) позволяет выделенного блок памяти из n элементов заданного размера.

Выделенную память можно привести к требуемому типу. Это не влияет на ее размер, но указывает компилятору, как генерировать код для обработки содержимого этой памяти.

Void*realloc( void*ptr,size-t size); позволяет изменить размер выделенной памяти. Если память вызвать не удалось, то она возвратит null. Новое значение может быть как больше существующего, так и меньше.

После работы с выделенной памятью, ее всегда следует освобождать вызовом функции Void free(void* ptr);. Параметр этой функции – указатель. Дальнейшее использование указателя на освобожденную память является опасным.

В С++ для выделения и освобождения памяти введены операторы new и delete.

Оператор new возвращает указатель на экземпляр объекта, созданного в памяти. Если память не выделена, выбрасываются исключения и нормальное продолжение программы становится невозможным. Любой указатель на динамически выделенную память должен далее использоваться в операторе delete.

Если в программе ошибочно не освобождаются области памяти, возникают “утечки” памяти, т.е. области не доступные для дальнейшей работы. Значительные утечки памяти могут приводить к аварийному завершению программ.