c / c ++ размещать в стеке

Я читал [1] о указателях стека и необходимости знать как ebp (начало стека для функции), так и esp (конец). В статье говорилось, что вам нужно знать и то и другое, потому что стек может расти, но я не понимаю, как это может быть возможно в c / c ++. (Я не говорю о другом вызове функции, потому что, на мой взгляд, это приведет к росту стека, выполнению некоторых операций, а затем рекурсивному извлечению и возврату в состояние перед вызовом)

Я провел небольшое исследование и видел только людей, которые говорили, что new выделяет в кучу. Но указатель будет локальной переменной, верно? И это известно во время компиляции и резервируется в стеке во время вызова функции.

Я начал думать, что, возможно, с циклами у вас есть неконтролируемое количество локальных переменных

int a;
for (int i = 0; i < n; ++i)
int b = i + 3;

но нет, это не выделяет n раз bи только 1 int зарезервирован так же, как и для a,

Итак … какой-нибудь пример?

[1): http://en.wikibooks.org/wiki/X86_Disassembly/Functions_and_Stack_Frames

2

Решение

Вы можете выделить память в стеке с alloca функция из stdlib. Я не рекомендую использовать эту функцию в рабочем коде. Это легко повредить ваш стек или получить переполнение стека.

5

Другие решения

Использование EBP больше для удобства. Можно просто использовать ESP. Проблема в том, что когда параметры в функции помещаются в стек, адрес относительно ESP всех переменных и параметров изменяется.

Устанавливая EBP в фиксированную, известную позицию в стеке, обычно между параметрами функции и локальными переменными, адрес всех этих элементов остается постоянным относительно EBP в течение всего времени существования функции. Это также может помочь с отладкой, так как значение ESP в конце функции должно равняться значению EBP.

Единственный известный мне способ неопределенного роста стека во время компиляции — многократное использование alloca.

1

Указатель действительно размещен в стеке. И размер обычно составляет 4 или 8 байтов на 32 и 64-битных архитектурах соответственно. Таким образом, вы знаете размер указателя статически, во время компиляции, и вы можете сохранить их в стеке, если захотите.

Этот указатель может указывать на свободное хранилище, и вы можете выделять ему память динамически — без необходимости заранее знать размер. Более того, обычно хорошей идеей является сохранение стековых фреймов пустыми, и компиляторы даже «принудительно» применяют это с (настраиваемыми) ограничениями. MSVC имеет 1 МБ, если я правильно помню.

Так что нет, вы не можете создать стековый фрейм размером, который неизвестен во время компиляции. Ваш кадр стека кода, который вы разместили, будет иметь место для 3 целых чисел (a, b, i). (И, возможно, некоторые отступы, теневое пространство и т. Д. Не имеют значения.) (ТЕХНИЧЕСКИ возможно расширить размер стековых кадров во время выполнения, но вы просто не хотите делать это почти никогда.)

0