Для кучи характерен «рост вверх». Это означает, что последовательные элементы, добавляемые к куче, добавляются по адресам, численно превосходящим предыдущие. Куча обычно начинается сразу после области BSS сегмента данных.
static
.
В большинстве архитектур параметры функций также помещаются в стек наряду с «невидимой» учетной информацией, генерируемой компилятором, такой, как возвращаемое функцией значение и адрес возврата для перехода из функции к месту, откуда произошел вызов. (В некоторых архитектурах для этого используются регистры.) Именно использование стека для параметров функций и возвращаемых ими значений делает удобным написание
Рис. 3.1. Адресное пространство Linux/Unix
Хотя перекрывание стека и кучи теоретически возможно, операционная система предотвращает этот случай, и любая программа, пытающаяся это сделать, напрашивается на неприятности. Это особенно верно для современных систем, в которых адресные пространства большие и интервал между верхушкой стека и концом кучи значителен. Различные области памяти могут иметь различную установленную на память аппаратную защиту. Например, сегмент текста может быть помечен «только для исполнения», тогда как у сегментов данных и стека разрешение на исполнение может отсутствовать. Такая практика может предотвратить различные виды атак на безопасность. Подробности, конечно, специфичны для оборудования и операционной системы, и они могут со временем меняться. Стоит заметить, что стандартные как С, так и C++ позволяют размещать элементы с атрибутом const
в памяти только для чтения. Сводка взаимоотношений различных сегментов приведена в табл. 3.1.
Таблица 3.1. Сегменты исполняемой программы и их размещение
Память программы | Сегмент адресного пространства | Секция исполняемого файла |
---|---|---|
Код | Text | Text |
Инициализированные данные | Data | Data |
BSS | Data | BSS |
Куча | Data | |
Стек | Stack |
Программа size
распечатывает размеры в байтах каждой из секций text, data и BSS вместе с общим размером в десятичном и шестнадцатеричном виде. (Программа ch03-memaddr.с
показана далее в этой главе; см. раздел 3.2.5 «Исследование адресного пространства».)
$ cc -o ch03-memaddr.с -о ch03-memaddr /* Компилировать программу */
$ ls -l ch03-memaddr /* Показать общий размер */
-rwxr-xr-x 1 arnold devel 12320 Nov 24 16:45 ch03-memaddr
$ size ch03-memaddr /* Показать размеры компонентов */
text data bss dec hex filename
1458 276 8 1742 6ce ch03-memaddr
$ strip ch03-memaddr /* Удалить символы */
$ ls -l ch03-memaddr /* Снова показать общий размер */
-rwxr-xr-x 1 arnold devel 3480 Nov 24 16:45 ch03-memaddr
$ size ch03-memaddr /* Размеры компонентов не изменились */
text data bss dec hex filename
1458 276 8 1742 6ce ch03-memaddr