Можно ли разместить в стеке? - PullRequest
1 голос
/ 16 августа 2011

Функция malloc всегда выделяет память в куче. Однако, изучая статью Escape Analylis в Википедии , я узнал, что в качестве оптимизации компилятор может преобразовывать распределения кучи в распределения стека. Например, если он видит, что выделенная память используется только и затем освобождается внутри функции.

Теперь мой вопрос: есть ли способ, которым программист может сделать это сам? То есть выделить память по стеку? Я знаю, что C99 позволяет указывать переменную в качестве размера для объявления массива, но, скажем, программист хочет изменить его размер. Можно ли это сделать?

Ответы [ 3 ]

5 голосов
/ 16 августа 2011

alloca() - это то, что вы ищете.Конечно, если вы знаете размеры ваших структур статически, лучше использовать вместо них локальные переменные.

4 голосов
/ 16 августа 2011

C99 также позволяет вам распределять массивы переменной длины (VLA) и другие переменные в любой точке внутри функции, а не только в начале, поэтому ваша точка зрения о возможности выделения памяти в другом месте не имеет значения.

Вы можете просто подключить:

int arr[somevar];

в любом месте функции и включите ее.

С VLA вам больше не нужно беспокоиться об использовании malloc/free (или печально известной alloca, доступной в некоторых реализациях, что было еще одним способом выполнения на основе стека, a означает automatic) для произвольно расположенных распределений переменного размера.

Если вам нужна возможность изменения размера, вам все равно придется использовать стандартные функции выделения памяти, такие как malloc и realloc. VLA не обеспечивают этот уровень функциональности (пока).

0 голосов
/ 16 августа 2011

Насколько мне известно, преобразование выделений кучи в выделение стека - это дело библиотеки, а не то, что компилятор может контролировать. Действительно, в Linux malloc использует системный вызов brk (который изменяет размер стека) вместо использования mmap, за исключением страниц большего размера.

Цитировать из источника :

The old goals we kept are
  1) try to get the long lived large allocations to use mmap()
  2) really large allocations should always use mmap()
  and we're adding now:
  3) transient allocations should use brk() to avoid forcing the kernel
     having to zero memory over and over again
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...