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