Вход/Регистрация
Linux программирование в примерах
вернуться

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

Шрифт:

36

37 printf("BSS Locations:\n");

38 printf("\tAddress of bss_var: %p\n", &bss_var);

39

40 b = sbrk((ptrdiff_t)32); /* увеличить адресное пространство */

41 nb = sbrk((ptrdiff_t)0);

42 printf("Heap Locations:\n");

43 printf("\tInitial end of heap: %p\n", b);

44 printf("\tNew end of heap: %p\n", nb);

45

46 b = sbrk((ptrdiff_t)-16); /* сократить его */

47 nb = sbrk((ptrdiff_t)0);

48 printf("\tFinal end of heap: %p\n", nb);

49 }

50

51 void

52 afunc(void)

53 {

54 static int level = 0; /* уровень рекурсии */

55 auto int stack_var; /* автоматическая переменная в стеке */

56

57 if (++level == 3) /* избежать бесконечной рекурсии */

58 return;

59

60 printf("\tStack level %d: address of stack_var: %p\n",

61 level, &stack_var);

62 afunc; /* рекурсивный вызов */

63 }

Эта программа распечатывает местонахождение двух функций

main
и
afunc
(строки 22–23). Затем она показывает, как стек растет вниз, позволяя
afunc
(строки 51–63) распечатать адреса последовательных экземпляров ее локальной переменной
stack_var
. (
stack_var
намеренно объявлена как
auto
, чтобы подчеркнуть, что она находится в стеке.) Затем она показывает расположение памяти, выделенной с помощью
alloca
(строки 28–32). В заключение она печатает местоположение переменных данных и BSS (строки 34–38), а затем памяти, выделенной непосредственно через
sbrk
(строки 40–48). Вот результаты запуска программы на системе Intel GNU/Linux:

$ ch03-memaddr

Text Locations:

 Address of main: 0x804838c

 Address of afunc: 0x80484a8

Stack Locations:

 Stack level 1: address of stack_var: 0xbffff864

 Stack level 2: address of stack_var: 0xbffff844

/* Стек растет вниз */

 Start of alloca'ed array: 0xbffff860

 End of alloca'ed array: 0xbffff87f

/* Адреса находятся в стеке */

Data Locations:

 Address of data_var: 0x80496b8

BSS Locations:

 Address of bss_var: 0x80497c4

/* BSS выше инициализированных данных */

Heap Locations:

 Initial end of heap: 0x80497c8

/* Куча непосредственно над BSS */

 New end of heap: 0x80497e8

/* И растет вверх */

 Final end of heap: 0x80497d8

/* Адресные пространства можно сокращать */

3.3. Резюме

• У каждой программы Linux и (Unix) есть различные области памяти. Они хранятся в разных частях файла исполняемой программы на диске. Некоторые из секций загружаются при запуске программы в одну и ту же область памяти. Все запушенные экземпляры одной и той же программы разделяют исполняемый код (сегмент текста). Программа

size
показывает размеры различных областей переместимых объектных файлов и полностью скомпонованных исполняемых файлов.

• В адресном пространстве запушенной программы могут быть дыры, а размер адресного пространства может изменяться при выделении и освобождении памяти. На современных системах адрес 0 не является частью адресного пространства, поэтому не пытайтесь разыменовывать указатели

NULL
.

• На уровне языка С память выделяется с помощью одной из функций

malloc
,
calloc
или
realloc
. Память освобождается с помощью
free
. (Хотя с помощью
realloc
можно делать все, использование ее таким образом не рекомендуется.) Освобожденная память обычно не удаляется из адресного пространства; вместо этого она используется повторно при последующих выделениях.

• Необходимо предпринять чрезвычайные меры осторожности в следующих случаях

 • освобождать лишь память, выделенную с помощью соответствующих процедур,

 • освобождать память один и только один раз,

 • освобождать неиспользуемую память и

 • не допускать «утечки» динамически выделяемой памяти.

• POSIX предоставляет для удобства функцию

strdup
, a GLIBC предоставляет функции
getline
и
getdelim
для чтения строк произвольной длины. Функции интерфейса низкоуровневых системных вызовов
brk
и
sbrk
предоставляют непосредственный, но примитивный доступ к выделению и освобождению памяти. Если вы не создаете свой собственный распределитель памяти, следует избегать их. Существует функция
alloca
для выделения памяти в стеке, но ее использование не рекомендуется. Подобно умению распознавать ядовитый плющ, про нее нужно знать лишь для того, чтобы избегать ее.

  • Читать дальше
  • 1
  • ...
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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