Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

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

Обсуждение ряда полезных инструментов для отладки динамической памяти см в разделе 15.5.2 «Отладчики выделения памяти».

3.2.1.4. Изменение размера:

realloc

Динамическая память имеет существенное преимущество перед статически объявленными массивами, поскольку это позволяет использовать столько памяти,

сколько нужно, и не больше. Не нужно объявлять глобальный, статический или локальный массив фиксированного размера и надеяться, что он: (а) достаточно большой и (б) не слишком большой. Вместо этого можно выделить ровно столько, сколько нужно, не больше и не меньше.

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

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

int new_count;

size_t new_amount;

struct coord *newcoords; /* установить, например: */

new_count = count * 2; /* удвоить размер памяти */

new_amount = new_count * sizeof(struct coord);

newcoords =

 (struct coord*)realloc(coordinates, new_amount);

if (newcoords == NULL) {

 /* сообщить об ошибке, восстановить или прервать */

}

coordinates = newcoords;

/* продолжить использование coordinates ... */

Как и в случае с

malloc
, шаги стереотипны по природе и сходны по идее.

1. Вычислить новый выделяемый размер в байтах.

2. Вызвать

realloc
с оригинальным указателем, полученным от
malloc
(или от
calloc
или предыдущего вызова
realloc
) и с новым размером.

3. Привести тип и присвоить возвращенное

realloc
значение. Подробнее обсудим дальше.

4. Как и для

malloc
, проверить возвращенное значение, чтобы убедиться, что оно не равно NULL. Вызов любой функции выделения памяти может завершиться неудачей.

При увеличении размера блока памяти

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

В любом случае вы можете предположить, что если

realloc
не возвращает
NULL
, старые данные были скопированы для вас в новый участок памяти. Более того, старый указатель больше недействителен, как если бы вы вызвали
free
с ним, и использовать его больше не следует. Это верно для всех указателей на
этот блок данных, а не только для того, который использовался при вызове
free
.

Возможно, вы заметили, что в нашем примере для указания на измененный блок памяти использовалась отдельная переменная. Можно было бы (хотя это плохая идея) использовать ту же самую переменную, как здесь:

coordinates = realloc(coordinates, new_amount);

Это плохо по следующей причине. Когда

realloc
возвращает
NULL
, первоначальный указатель все еще действителен; можно безопасно продолжить использовать эту память. Но если вы повторно используете ту же самую переменную и
realloc
возвращает
NULL
, вы теряете указатель на первоначальную память. Эту память больше нельзя использовать. Что еще важнее, эту память невозможно освободить! Это создает утечку памяти, которую нужно избежать.

Для версии

realloc
в стандартном С есть некоторые особые случаи: когда аргумент
ptr
равен
NULL
,
realloc
действует подобно
malloc
и выделяет свежий блок памяти. Когда аргумент
size
равен 0,
realloc
действует подобно
free
и освобождает память, на которую указывает
ptr
. Поскольку (а) это может сбивать с толку и (б) более старые системы не реализуют эту возможность, мы рекомендуем использовать
malloc
, когда вы имеете в виду
malloc
, и
free
, когда вы имеете в виду
free
.

Вот другой довольно тонкий момент [42] . Рассмотрим процедуру, которая содержит статический указатель на динамически выделяемые данные, которые время от времени должны расти. Процедура может содержать также автоматические (т.е. локальные) указатели на эти данные. (Для краткости, мы опустим проверки ошибок. В коде продукта не делайте этого.) Например:

void manage_table(void) {

 static struct table *table;

 struct table *cur, *p;

42

Он получен от реальной практики работы с

gawk
— Примеч. автора.

 int i;

 size_t count;

 ...

 table =

(struct table*)malloc(count * sizeof(struct table));

 /* заполнить таблицу */

 cur = &table[i]; /* указатель на 1-й элемент */

 ...

 cur->i = j; /* использование указателя */

 ...

 if (/* некоторое условие */) {

/* нужно увеличить таблицу */

Поделиться:
Популярные книги

Гвардия. (Дилогия)

Мусаниф Сергей Сергеевич
65. В одном томе
Фантастика:
научная фантастика
8.57
рейтинг книги
Гвардия. (Дилогия)

Я все еще царь. Книга XXXI

Дрейк Сириус
31. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я все еще царь. Книга XXXI

Латино-Иерусалимское королевство

Ришар Жан
История крестовых походов
Научно-образовательная:
история
6.25
рейтинг книги
Латино-Иерусалимское королевство

Академия

Сай Ярослав
2. Медорфенов
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.25
рейтинг книги
Академия

12

Санивский Сергей Анатолиевич
5.00
рейтинг книги
12

3ds Max 2008

Верстак Владимир
Видеосамоучитель
Компьютеры и Интернет:
программное обеспечение
5.00
рейтинг книги
3ds Max 2008

Неудержимый. Книга VI

Боярский Андрей
6. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга VI

Попала, или Кто кого

Юнина Наталья
Любовные романы:
современные любовные романы
5.88
рейтинг книги
Попала, или Кто кого

Управленческая элита. Как мы ее отбираем и готовим

Тарасов Владимир
Деловая литература:
управление, подбор персонала
5.00
рейтинг книги
Управленческая элита. Как мы ее отбираем и готовим

Том 14. Критические статьи, очерки, письма

Гюго Виктор
14. Собрание сочинений
Документальная литература:
критика
публицистика
5.00
рейтинг книги
Том 14. Критические статьи, очерки, письма

Философия и культура

Ильенков Эвальд Васильевич
Научно-образовательная:
философия
5.00
рейтинг книги
Философия и культура

В этом мире еще можно удивляться

Лейн МаККайла
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
В этом мире еще можно удивляться

Газлайтер. Том 18

Володин Григорий Григорьевич
18. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
6.80
рейтинг книги
Газлайтер. Том 18

Шум и ярость

Фолкнер Уильям Катберт
Проза:
классическая проза
8.36
рейтинг книги
Шум и ярость