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

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

Жанры

Linux программирование в примерах
Шрифт:

Но знать о низкоуровневых механизмах стоит, и конечно же, набор функций

malloc
реализован с помощью
sbrk
и
brk
.

3.2.4. Вызовы ленивых программистов:

alloca

«Опасность, Билл Робинсон! Опасность!»

– Робот -

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

alloca
; она объявлена следующим образом:

/* Заголовок в GNU/Linux, возможно, не на всех Unix-системах */

#include <alloca.h> /* Обычный */

void *alloca(size_t size);

Функция

alloca
выделяет
size
байтов из стека. Хорошо, что выделенная память исчезает после возвращения из функции. Нет необходимости явным образом освобождать память, поскольку это осуществляется автоматически, как в случае с локальными переменными.

На первый взгляд,

alloca
выглядит чем-то типа панацеи для программистов, можно выделять память, о которой можно вовсе не беспокоиться. Подобно Темной Стороне Силы, это, конечно, привлекает. И подобным же образом этого нужно избегать по следующим причинам:

• Функция не является стандартной; она не включена ни в какой стандарт, ни в ISO, ни в С или POSIX.

• Функция не переносима. Хотя она существует на многих системах Unix и GNU/Linux, она не существует на не-Unix системах. Это проблема, поскольку код часто должен быть многоплатформенным, выходя за пределы просто Linux и Unix.

• На некоторых системах

alloca
невозможно даже реализовать. Весь мир не является ни процессором Intel x86, ни GCC.

• Цитируя справку [45] (добавлено выделение): «Функция

alloca
зависит от машины и от компилятора. На многих системах ее реализация ошибочна. Ее использование не рекомендуется».

• Снова цитируя справку: «На многих системах

alloca
не может быть использована внутри списка аргументов вызова функции, поскольку резервируемая в стеке при помощи
alloca
память оказалась бы в середине стека в пространстве для аргументов функции».

45

alloca(3) — Примеч. науч. ред.

• Она потворствует неряшливому программированию. Тщательная и корректная работа с памятью не сложна; вам просто нужно подумать о том, что вы делаете, и планировать заранее.

GCC обычно использует встроенную версию функции, которая действует с использованием внутритекстового (inline) кода. В результате есть другие последствия

alloca
. Снова цитируя справку:

Факт, что код является внутритекстовым (inline), означает, что невозможно получить адрес этой функции или изменить ее поведение путем компоновки с другой библиотекой.

Внутритекстовый код часто состоит из одной инструкции, подгоняющей указатель стека, и не проверяет переполнение стека. Поэтому нет возврата

NULL
при ошибке.

Справочная страница не углубляется в описание проблемы со встроенной

alloca
GCC. Если есть переполнение стека, возвращаемое значение является мусором. И у вас нет способа сообщить об этом! Это упущение делает невозможным использование GCC
alloca
в устойчивом коде.

Все это должно убедить вас избегать

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

3.2.5. Исследование адресного пространства

Следующая программа,

ch03-memaddr.c
, подводит итог всему, что мы узнали об адресном пространстве. Она делает множество вещей, которые не следует делать на практике, таких, как вызовы
alloca
или непосредственные вызовы
brk
и
sbrk
.

1 /*

2 * ch03-memaddr.с --- Показать адреса секций кода, данных и стека,

3 * а также BSS и динамической памяти.

4 */

5

6 #include <stdio.h>

7 #include <malloc.h> /* для определения ptrdiff_t в GLIBC */

8 #include <unistd.h>

9 #include <alloca.h> /* лишь для демонстрации */

10

11 extern void afunc(void); /* функция, показывающая рост стека */

12

13 int bss_var; /* автоматически инициализируется в 0, должна быть в BSS */

14 int data_var = 42; /* инициализируется в не 0, должна быть

15 в сегменте данных */

16 int

17 main(int argc, char **argv) /* аргументы не используются */

18 {

19 char *p, *b, *nb;

20

21 printf("Text Locations:\n");

22 printf("\tAddress of main: %p\n", main);

23 printf("\tAddress of afunc: %p\n", afunc);

24

25 printf("Stack Locations.\n");

26 afunc;

27

28 p = (char*)alloca(32);

29 if (p != NULL) {

30 printf("\tStart of alloca'ed array: %p\n", p);

31 printf("\tEnd of alloca'ed array: %p\n", p + 31);

32 }

33

34 printf("Data Locations:\n");

35 printf("\tAddress of data_var: %p\n", &data_var);

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

Зайти и выйти

Суконкин Алексей
Проза:
военная проза
5.00
рейтинг книги
Зайти и выйти

Мастер порталов

Лисина Александра
8. Гибрид
Фантастика:
боевая фантастика
попаданцы
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Мастер порталов

Кодекс Охотника. Книга XXXIII

Винокуров Юрий
33. Кодекс Охотника
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Кодекс Охотника. Книга XXXIII

Дракон

Бубела Олег Николаевич
5. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.31
рейтинг книги
Дракон

An ordinary sex life

Астердис
Любовные романы:
современные любовные романы
love action
5.00
рейтинг книги
An ordinary sex life

Старый, но крепкий 5

Крынов Макс
5. Культивация без насилия
Фантастика:
рпг
аниме
уся
фэнтези
5.00
рейтинг книги
Старый, но крепкий 5

Локки 9. Потомок бога

Решетов Евгений Валерьевич
9. Локки
Фантастика:
фэнтези
попаданцы
героическая фантастика
боевая фантастика
5.00
рейтинг книги
Локки 9. Потомок бога

Хозяин Стужи 3

Петров Максим Николаевич
3. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
7.00
рейтинг книги
Хозяин Стужи 3

Мечник Вернувшийся 1000 лет спустя

Ткачев Андрей Юрьевич
1. Вернувшийся мечник
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Мечник Вернувшийся 1000 лет спустя

Я - злодейка в дораме. Сезон второй

Вострова Екатерина
2. Выжить в дораме
Фантастика:
уся
фэнтези
сянься
попаданцы
5.00
рейтинг книги
Я - злодейка в дораме. Сезон второй

Тринадцатый IV

NikL
4. Видящий смерть
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Тринадцатый IV

Бастард Императора. Том 13

Орлов Андрей Юрьевич
13. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Бастард Императора. Том 13

Ваше Сиятельство 2

Моури Эрли
2. Ваше Сиятельство
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Ваше Сиятельство 2

Рождественский детектив (сборник рассказов)

Полякова Татьяна Викторовна
Детективы:
прочие детективы
6.00
рейтинг книги
Рождественский детектив (сборник рассказов)