Linux программирование в примерах
Шрифт:
• В качестве одного операнда выражения сравнения (
==
, <
и т.д.), с целой константой в качестве другого операнда. Выражение сравнения может быть единственный контролирующим выражением цикла или условного оператора. • В качестве операнда унарного оператора '
!
', причем результирующее выражение является единственным контролирующим выражением цикла или условного оператора. • В качестве всего выражения оператора-выражения, возможно, приведенного к типу
void
. Например: (void)setjmp(buf);
В-третьих, если вы хотите изменить локальную переменную в функции,
setjmp
, после вызова и хотите, чтобы эта переменная сохранила свое последнее присвоенное после longjmp
значение, нужно объявить эту переменную как volatile
. В противном случае все локальные переменные, не являющиеся volatile
и изменившиеся после того, как была первоначально вызвана setjmp
, имеют неопределенные значения. (Обратите внимание, что сама переменная jmp_buf
не должна объявляться как volatile
.) Например: 1 /* ch12-setjmp.с --- демонстрирует setjmp/longjmp и volatile. */
2
3 #include <stdio.h>
4 #include <setjmp.h>
5
6 jmp_buf env;
7
8 /* comeback --- выполнение longjmp */
9
10 void comeback(void)
11 {
12 longjmp(env, 1);
13 printf("This line is never printed\n");
14 }
15
16 /* main - вызов setjmp, действия с переменными, вывод значений */
17
18 int main(void)
19 {
20 int i = 5;
21 volatile int j = 6;
22
23 if (setjmp(env) == 0) { /* первый раз */
24 i++;
25 j++;
26 printf("first time: i = %d, j = %d\n", i, j);
27 comeback));
28 } else /* второй раз */
29 printf("second time: i = %d, j = %d\n", i, j);
30
31 return 0;
32 }
В этом примере сохранение своего значения ко второму вызову
printf
гарантируется лишь
j (строка 21). Значение (строка 20) в соответствии со стандартом С 1999 г. не определено. Это может быть 6, может быть 5, а может даже какое-нибудь другое значение! В-четвертых, как описано в разделе 12.5.2 «Обработка масок сигналов:
sigsetjmp
и siglongjmp
», стандарт С 1999 г. не делает никаких утверждений о влиянии, если оно есть, setjmp
и longjmp
на состояние сигналов программы. Если это важно, вам придется вместо них использовать sigsetjmp
и siglongjmp
. В-пятых, эти процедуры содержат поразительные возможности для утечек памяти! Рассмотрим программу, в которой
main
вызывает setjmp
, а затем
malloc
динамическую память. Если наиболее глубоко вложенная функция делает longjmp
обратно в main
, указатели на динамическую память теряются. Взгляните на ch12-memleak.c
: 1 /* ch12-memleak.с --- демонстрирует утечки памяти с помощью setjmp/longjmp. */
2
3 #include <stdio.h>
4 #include <malloc.h> /* для определения ptrdiff_t в GLIBC */
5 #include <setjmp.h>
6 #include <unistd.h>
7
8 jmp_buf env;
9
10 void f1(void), f2(void);
11
12 /* main --- утечка памяти с помощью setjmp и longjmp */
13
14 int main(void)
15 {
16 char *start_break;
17 char *current_break;
18 ptrdiff_t diff;
19
20 start_break = sbrk((ptrdiff_t)0);
21
22 if (setjmp(env) == 0) /* первый раз */
23 printf("setjmp called\n");
24
25 current_break = sbrk((ptrdiff_t) 0);
26
27 diff = current_break - start_break;
28 printf("memsize = %ld\n", (long)diff);
29
30 f1;
31
32 return 0;
33 }
34
35 /* f1 --- выделяет память, осуществляет вложенный вызов */
36
37 void f1(void)
38 {
39 char *p = malloc(1024);
40
41 f2;
42 }
43
44 /* f2 --- выделяет память, выполняет longjmp */
45
46 void f2(void)
47 {
48 char *p = malloc(1024);
49
50 longjmp(env, 1);
51 }
Эта программа устанавливает бесконечный цикл, используя
setjmp
и longjmp
. Строка 20 использует для нахождения текущего начала кучи sbrk
(см. раздел 3.2.3 «Системные вызовы: brk
и sbrk
»), а затем строка 22 вызывает setjmp
. Строка 25 получает текущее начало кучи; это место каждый раз изменяется, поскольку longjmp
повторно входит в код. Строки 27–28 вычисляют, сколько было выделено памяти, и выводят это количество. Вот что происходит при запуске:
Поделиться:
Популярные книги
Мастер Разума V
5. Мастер Разума
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Последний из рода Демидовых
Фантастика:
детективная фантастика
попаданцы
аниме
5.00
рейтинг книги
Любовь Носорога
Любовные романы:
современные любовные романы
9.11
рейтинг книги
Авиатор: назад в СССР 12
12. Покоряя небо
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Толян и его команда
6. Девяностые
Фантастика:
попаданцы
альтернативная история
7.17
рейтинг книги
Академия
2. Клан Волка
Фантастика:
боевая фантастика
5.40
рейтинг книги
Изгой. Пенталогия
Изгой
Фантастика:
фэнтези
9.01
рейтинг книги
Неудержимый. Книга IX
9. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Невеста
Любовные романы:
любовно-фантастические романы
эро литература
8.54
рейтинг книги
Энфис 2
2. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Убийца
3. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.26
рейтинг книги
Лорд Системы
1. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
4.00
рейтинг книги
Делегат
6. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Невеста напрокат
Любовные романы:
любовно-фантастические романы
6.20