Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ШПОРЫ_ТЯП.docx
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
1.63 Mб
Скачать

33. Распределение памяти. Стек времени выполнения. Определение области видимости.

Распределение глобальной памяти осуществляется достаточно просто: область пространства (куча (heap)) увеличивается настолько, насколько это необходимо. Освобождение этой области памяти осуществляется намного сложнее, поскольку данный процесс трудно связать с процессом распределения памяти. Существует два основных вопроса, связанных с распределением и освобождением глобальной памяти.

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

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

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

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

В языке С для переменных имеется четыре возможных класса памяти: static, auto, extern и register. Для статических переменных память выделяется на все время программы. Для переменных класса auto (класс по умолчанию) память выделена до момента завершения работы составного оператора, в котором были объявлены данные переменные. Таким образом, более удобной для данных переменных является память в стеке. Для переменных класса extern память выделяется в другом файле. Значения переменных класса register хранятся в регистре, если компилятор способен организовать это удобным образом, в противном случае такие переменные эквивалентны переменным auto.

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

p = malloc(sizeof(int));

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

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]