[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 Сдвиг границы выделяемой памяти

Системные вызовы brk(2) и sbrk(2) могут изменять размер сегмента
данных с помощью изменения значения границы выделяемой памяти.  Новое
значение границы передается системному вызову brk(2) как аргумент.
Системному вызову sbrk(2) передается целое значение, которое
определяет насколько изменится значение границы выделяемой памяти.
Текущее значение границы выделяемой памяти может быть получено вызовом
sbrk(2) с нулевым аргументом, т.е. ~currentbv=sbrk(0).
Заново выделенная память, полученная с помощью brk(2) или sbrk(2),
инициализируется нулями. Тем не менее, если эта память вновь
выделяется, ее содержание неопределено.
Значение границы выделяемой памяти не может быть больше ограничения,
определенного в системе, или располагаться в стеке, текстовом сегменте
или между &etext и &end. Системные вызовы brk(2) и sbrk(2) возвращают
-1 в случае неуспеха и устанавливают errno для указания причины.
Поэтому для контроля неуспеха надо сравнивать значение, возвращаемое
sbrk(2), с (void*) -1.
В отличие от сегмента данных, стек программы автоматически
увеличивается и уменьшается с каждым вызовом функции и выходом из нее,
соответственно.
                   СДВИГ ГРАНИЦЫ ВЫДЕЛЯЕМОЙ ПАМЯТИ
brk(2)

ИМЯ

      brk, sbrk - изменяют размер сегмента данных

ИСПОЛЬЗОВАНИЕ

      #include <unistd.h>

      int brk (void *endds);
      void *sbrk(int incr);

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

      успех:
          brk - 0
          sbrk - предыдущее значение границы выделяемой памяти

      неуспех - -1 и errno установлена
               Сдвиг границы выделяемой памяти - Пример

Этот пример демонстрирует работу системных вызовов brk(2) и sbrk(2)
следующим образом:
   11-13  Печатаются границы сегментов.

   15-16  Печатается  текущее   значение  границы  выделяемой  памяти.
          Заметим, что оно равно &end.

   18     Граница выделяемой памяти увеличивается на 512.

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

   28     Граница выделяемой памяти увеличивается на 64.

   33     Сегмент данных уменьшается на 512 байтов.

Эта программа демонстрируется следующим образом:
$ sbrk1
  1 The  program text ends at 20000030200
  2 The  initialized data ends at 20000054350
  3 The uninitialized data ends at 20000061530
  4
  5 Current break value is 20000061530
  6
  7 brk returned . . . . 0
  8 Current break value is 20000062530
  9
 10 brk returned . . . . -1
 11 Current break value is 20000062530
 12
 13 sbrk returned . . . . 20000062530
 14 Current break value is 20000062630
 15
 16 sbrk returned . . . . 20000062630
 17 Current break value is 20000061630
 18

Файл: sbrk1.c
               СДВИГ ГРАНИЦЫ ВЫДЕЛЯЕМОЙ ПАМЯТИ - ПРИМЕР
 1 #include <unistd.h>
 2 #include <stdio.h>
 3
 4 extern int etext, edata, end;
 5
 6 main()
 7 {
 8      int ret;
 9      char *bv;
10
11      printf("The  program text ends at %07o\n", &etext);
12      printf("The  initialized data ends at %07o\n", &edata);
13      printf("The uninitialized data ends at %07o\n\n", &end);
14
15      bv = sbrk(0);
16      printf("Current break value is %07o\n\n", bv);
17
18      ret = brk(bv + 512);    /* 01000 */
19      printf("brk returned . . . . %d\n", ret);
20      bv = sbrk(0);
21      printf("Current break value is %07o\n\n", bv);
22
23      ret = brk(&ret);
24      printf("brk returned . . . . %d\n", ret);
25      bv = sbrk(0);
26      printf("Current break value is %07o\n\n", bv);
27
28      bv = sbrk(64);  /* 0100 */
29      printf("sbrk returned . . . . %07o\n", bv);
30      bv = sbrk(0);
31      printf("Current break value is %07o\n\n", bv);
32
33      bv = sbrk(-512); /* memory deallocation: -01000 */
34      printf("sbrk returned . . . . %07o\n", bv);
35      bv = sbrk(0);
36      printf("Current break value is %07o\n\n", bv);
37 }