Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Подбельский Фомин_Программирование на языке СИ_...doc
Скачиваний:
360
Добавлен:
10.08.2019
Размер:
53.81 Mб
Скачать

Динамическая память

Динамическая память - это память, выделяемая в процессе выполнения программы. А вот на вопрос: "Глобальный или локальный объект размещен в динамической памяти?" попытаемся найти правильный ответ.

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

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

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

• указатель (на участок динамической памяти) определен как локальный объект автоматической памяти. В этом случае выделенная память будет недоступна при выходе за пределы блока локализации указателя, и ее нужно освободить перед выходом из блока;

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

• указатель является глобальным объектом по отношению к блоку. Динамическая память доступна во всех блоках, где "виден" указатель. Память нужно освободить только по окончании ее использования.

Проиллюстрируем второй вариант, когда объект динамической памяти связан со статическим внутренним (локализованным) указателем:

Результат выполнения программы:

Некоторая небрежность предыдущей программы - выделенный функцией malloc( ) участок памяти явно не освобождается функцией free( ).

В следующей программе указатель на динамический участок памяти — глобальный объект:

Результат выполнения программы:

Динамический объект создается в основной функции и связывается с указателем uk. Там же он явным присваиванием получает начальное значение 'А'. За счет глобальности указателя динамический объект доступен в обоих функциях main( ) и dynam 1 ( ). При выполнении цикла в функции main( ) и внутри функции dynam 1 ( ) изменяется значение динамического объекта.

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

Внешние объекты.

Внешние объекты. Здесь в конце главы, посвященной функциям, самое подходящее время, чтобы взглянуть в целом на программу, состоящую из набора функций, размещенных в нескольких текстовых файлах. Именно такой вид обычно имеет более или менее серьезная программа на языке Си. Отдельный файл с текстами программы иногда называют программным модулем, но нет строгих терминологических соглашений относительно модулей или файлов с текстами программы. На рис. 5.3 приведена схема программы, текст которой находится в двух файлах. Программа, как мы уже неоднократно говорили, представляет собой совокупность функций. Все функции внешние, так как внутри функции по правилам языка Си нельзя определить другую функцию. У всех функций, даже размещенных в разных файлах, должны быть различные имена. Одинаковые имена функций должны относиться к одной и той же функции.

Кроме функций, в программе могут использоваться внешние_объекты - переменные, указатели, массивы и т.д. Внешние объекты должны быть определены вне текста функций.

Внешние объекты могут быть доступны из многих функций программы, однако эта доступность не всегда реализуется автоматически - в ряде случаев нужно дополнительное вмешательство программиста. Если объект определен в начале файла с программой, то он является глобальным для всех функций, размещенных в файле, и доступен в них без всяких дополнительных предписаний. (Ограничение - если внутри функции имя глобального объекта использовано в качестве имени внутреннего объекта, то внешний объект становится недостижимым, т.е. "невидимым" в теле именно этой функции.) На рис. 5.3:

• объект X: доступен в fl 1( ), f!2( ) как глобальный; доступен как внешний в файле 2 только в тех функциях, где будет помещено описание extern X;

• объект Y: доступен как глобальный в f21( ) и f22( ); доступен как внешний в тех функциях файла 1, где будет помещено описание extern Y;

• объект Z: доступен как глобальный в f22( ) и во всех функциях файла 1 и файла 2, где помещено описание extern Z.

Рис. 5.3. Схема программы, размещенной в двух файлах

Если необходимо, чтобы внешний объект был доступен для функций из другого файла или функций, размещенных выше определения объекта, то он должен быть перед обращением дополнительно описан с использованием дополнительного ключевого слова extern. (Наличие этого слова по умолчанию предполагается и для всех функций, т.е. не требуется в их прототипах.) Такое описание, со спецификатором слова extern, может помещаться в начале файла, и тогда объект доступен во всех функциях файла. Однако это описание может быть размещено в теле одной функции, тогда объект доступен именно в ней.

Описание внешнего объекта не есть его определение. Помните: в определении объекту всегда выделяется память, и он может быть инициализирован. Примеры определений:

В описаниях инициализация невозможна, нельзя указать и количество элементов массивов:

Содержательные примеры, иллюстрирующие особенности применения внешних объектов в "многофайловых" программах, приведены в главе 8.