Общий размер загруженного в память из файла в 12 320 байтов всего лишь 1742 байта. Большую часть этого места занимают
strip
удаляет символы из объектного файла. Для большой программы это может сохранить значительное дисковое пространство ценой невозможности отладки дампа ядра[40], если таковой появится (На современных системах об этом не стоит беспокоиться, не используйте strip
.) Даже после удаления символов файл все еще больше, чем загруженный в память образ, поскольку формат объектного файла содержат дополнительные данные о программе, такие, как использованные разделяемые библиотеки, если они есть.[41]Наконец, упомянем
3.2. Выделение памяти
Четыре библиотечные функции образуют основу управления динамической памятью С Мы опишем сначала их, затем последуют описания двух системных вызовов, поверх которых построены эти библиотечные функции. Библиотечные функции С, в свою очередь, обычно используются для реализации других выделяющих память библиотечных функций и операторов C++ new
delete
.Наконец, мы обсудим функцию, которую часто используют, но которую мы не рекомендуем использовать.
3.2.1. Библиотечные вызовы: malloc()
calloc()
, realloc()
, free()
Динамическую память выделяют с помощью функций malloc()
calloc()
. Эти функции возвращают указатели на выделенную память. Когда у вас есть блок памяти определенного первоначального размера, вы можете изменить его размер с помощью функции realloc()
. Динамическая память освобождается функцией free()
.Отладка использования динамической памяти сама по себе является важной темой. Инструменты для этой цели мы обсудим в разделе 15.5.2 «Отладчики выделения памяти».
3.2.1.1. Исследование подробностей на языке С
Вот объявления функций из темы справки GNU/Linux
#include
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_t
size
_t является unsigned long
, но лучше явно использовать size_t
вместо простого целого типа unsigned
.Тип ptrdiff_t
#define MAXBUF ...
char *p;
char buf[MAXBUF];
ptrdiff_t where;
p = buf;
while (/* некоторое условие */) {
...
p += something;
...
where = p - buf; /* какой у нас индекс? */
}
Заголовочный файл
size_t
), он определяет также константу препроцессора NULL
, которая представляет «нуль» или недействительный указатель. (Это нулевое значение, такое, как 0 или '((void*)0)
'. Явное использование 0 относится к стилю С++; в С, однако, NULL
является предпочтительным, мы находим его гораздо более читабельным для кода С.)3.2.1.2. Начальное выделение памяти: malloc()