Linux программирование в примерах | страница 69



при ошибке.

Справочная страница не углубляется в описание проблемы со встроенной >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

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

>8  #include

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

>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);

>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) /* избежать бесконечной рекурсии */