[<<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 }