Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"

Рис. 3.1. Адресное пространство Linux/Unix
Хотя перекрывание стека и кучи теоретически возможно, операционная система предотвращает этот случай, и любая программа, пытающаяся это сделать, напрашивается на неприятности. Это особенно верно для современных систем, в которых адресные пространства большие и интервал между верхушкой стека и концом кучи значителен. Различные области памяти могут иметь различную установленную на память аппаратную защиту. Например, сегмент текста может быть помечен «только для исполнения», тогда как у сегментов данных и стека разрешение на исполнение может отсутствовать. Такая практика может предотвратить различные виды атак на безопасность. Подробности, конечно, специфичны для оборудования и операционной системы, и они могут со временем меняться. Стоит заметить, что стандартные как С, так и C++ позволяют размещать элементы с атрибутом
constТаблица 3.1. Сегменты исполняемой программы и их размещение
| Память программы | Сегмент адресного пространства | Секция исполняемого файла |
|---|---|---|
| Код | Text | Text |
| Инициализированные данные | Data | Data |
| BSS | Data | BSS |
| Куча | Data | |
| Стек | Stack |
Программа
sizech03-memaddr.с$ <b>cc -o ch03-memaddr.с -о ch03-memaddr</b> /* Компилировать программу */$ <b>ls -l ch03-memaddr</b> /* Показать общий размер */-rwxr-xr-x 1 arnold devel 12320 Nov 24 16:45 ch03-memaddr$ <b>size ch03-memaddr</b> /* Показать размеры компонентов */text data bss dec hex filename1458 276 8 1742 6ce ch03-memaddr$ <b>strip ch03-memaddr</b> /* Удалить символы */$ <b>ls -l ch03-memaddr</b> /* Снова показать общий размер */-rwxr-xr-x 1 arnold devel 3480 Nov 24 16:45 ch03-memaddr$ <b>size ch03-memaddr</b> /* Размеры компонентов не изменились */text data bss dec hex filename1458 276 8 1742 6ce ch03-memaddrОбщий размер загруженного в память из файла в 12 320 байтов всего лишь 1742 байта. Большую часть этого места занимают символы (symbols), список имен переменных и функций программы. (Символы не загружаются в память при запуске программы.) Программа
stripstripНаконец, упомянем потоки (threads), которые представляют несколько цепочек исполнения в рамках единственного адресного пространства. Обычно у каждого потока имеется свой собственный стек, а также способ получения локальных данных потока, т.е. динамически выделяемых данных для персонального использования этим потоком. Мы больше не будем рассматривать в данной книге потоки, поскольку это является продвинутой темой.
3.2. Выделение памяти
Четыре библиотечные функции образуют основу управления динамической памятью С Мы опишем сначала их, затем последуют описания двух системных вызовов, поверх которых построены эти библиотечные функции. Библиотечные функции С, в свою очередь, обычно используются для реализации других выделяющих память библиотечных функций и операторов C++
newdeleteНаконец, мы обсудим функцию, которую часто используют, но которую мы не рекомендуем использовать.
3.2.1. Библиотечные вызовы:
malloc()calloc()realloc()free()Динамическую память выделяют с помощью функций
malloc()calloc()realloc()free()Отладка использования динамической памяти сама по себе является важной темой. Инструменты для этой цели мы обсудим в разделе 15.5.2 «Отладчики выделения памяти».
3.2.1.1. Исследование подробностей на языке С
Вот объявления функций из темы справки GNU/Linux malloc(3):
#include <stdlib.h> /* ISO С */void *calloc(size_t nmemb, size_t size); /* Выделить и инициализировать нулями */void *malloc(size_t size); /* Выделить без инициализации */void free(void *ptr); /* Освободить память */void *realloc(void *ptr, size_t size); /* Изменить размер выделенной памяти */Функции выделения памяти возвращают тип
void*Тип
size_tsizeunsigned longsize_tunsigned