Linux программирование в примерах
Linux программирование в примерах читать книгу онлайн
В книге рассмотрены вопросы, связанные с программированием под Linux: файловый ввод/вывод, метаданные файлов, основы управления памятью, процессы и сигналы, пользователи и группы, вопросы интернационализации и локализации, сортировка, поиск и многие другие. Много внимания уделено средствам отладки, доступным под GNU Linux. Все темы иллюстрируются примерами кода, взятого из V7 UNIX и GNU. Эта книга может быть полезна любому, кто интересуется программированием под Linux.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Как и в случае с
malloc()
1. Вычислить новый выделяемый размер в байтах.
2. Вызвать
realloc()
malloc()
calloc()
realloc()
3. Привести тип и присвоить возвращенное
realloc()
4. Как и для
malloc()
При увеличении размера блока памяти
realloc()
realloc()
В любом случае вы можете предположить, что если
realloc()
NULL
free()
free()
Возможно, вы заметили, что в нашем примере для указания на измененный блок памяти использовалась отдельная переменная. Можно было бы (хотя это плохая идея) использовать ту же самую переменную, как здесь:
coordinates = realloc(coordinates, new_amount);
Это плохо по следующей причине. Когда
realloc()
NULL
realloc()
NULL
Для версии
realloc()
ptr
NULL
realloc()
malloc()
size
realloc()
free()
ptr
malloc()
malloc()
free()
free()
Вот другой довольно тонкий момент [42]. Рассмотрим процедуру, которая содержит статический указатель на динамически выделяемые данные, которые время от времени должны расти. Процедура может содержать также автоматические (т.е. локальные) указатели на эти данные. (Для краткости, мы опустим проверки ошибок. В коде продукта не делайте этого.) Например:
void manage_table(void) {
static struct table *table;
struct table *cur, *p;
int i;
size_t count;
...
table =
(struct table*)malloc(count * sizeof(struct table));
/* заполнить таблицу */
cur = &table[i]; /* указатель на 1-й элемент */
...
cur->i = j; /* использование указателя */
...
if (/* некоторое условие */) {
/* нужно увеличить таблицу */
count += count/2;
p =
(struct table*)realloc(table, count * sizeof(struct table));
table = p;
}
cur->i = j; /* ПРОБЛЕМА 1: обновление элемента таблицы */
other_routine(); /* ПРОБЛЕМА 2: см. текст */
cur->j = k; /* ПРОБЛЕМА 2: см. текст */
...
}
Это выглядит просто;
manage_table()
В строке, помеченной '
ПРОБЛЕМА 1
cur
table
realloc()
cur
table
realloc()
table
cur = &table[i];
Две строки, помеченные '
ПРОБЛЕМА 2
other_routine()
manage_table()
table
other_routine()
Можно подумать (что мы вначале и сделали), что единственным решением является знать это и добавить после вызова функции переназначение
cur