2012-09-05 2 views
2

Насколько я понимаю, каждый поток обычно получает только один стек (в то время как все потоки в процессе обычно разделяют кучу). Я всегда думал, что стек используется для хранения значения счетчика программ (ПК) при вызове функции. Но затем я где-то читал, что определенные типы переменных, такие как integer или boolean, также выделяются в стек. Поскольку значения в стеках управляются строгим методом FILO, как эти переменные могут быть восстановлены в любое время?Как можно получить переменные в любое время, если они выделены в стек?

Например, после объявления int a, b, c;, я могу делать все, что захочу, этим переменным в любом порядке в любое время в пределах их объема. Как это делается? Почему нет значения c в верхней части стека и, следовательно, скрывает значения a, b?

ответ

1

Стек вызовов также используется для локальных переменных, а также для передачи параметров в функцию.

Вы правы в том, что в стеке передаются «типы значений», тогда как ссылочные типы выделяются в куче, но когда ссылочный тип используется в качестве параметра, указатель на это местоположение кучи будет по-прежнему передаваться стек.

Хотя стеки обычно воспринимаются как LIFO-буферы, существуют также фреймы или базовые указатели, связанные с стеком вызовов, которые могут использоваться для прямого доступа к памяти выше или ниже текущего указателя стека. Таким образом, функции могут по-прежнему иметь произвольный доступ к параметрам без изменения указателя стека.

Этот diagram from Wikipedia может помочь визуализировать это, хотя обратите внимание, что многие утверждают, что стек должен расти «вниз».

Этот блог here объясняет Intel вызов стеков

1

Во-первых, я хотел бы предложить, что вы должны исследовать стек в общем немного больше (см Wikipedia и Stack Explanation и другие через прибегая к помощи/CS книги).

Однако для вашего конкретного вопроса все переменные, которые не являются кучей, находятся в стеке. Обычно это включает в себя все, что вы определяете в пределах определенной функции, которая не распределяется непосредственно в кучу (через оператор new на C++ и Java). На некоторых языках все выделено в кучу, и только указатели на эти структуры кучи хранятся в стеке (например, на Python). Вы увидите множество этих незначительных изменений между языками.

Таким образом, ваше утверждение о целых и логических значениях всегда находится в стеке неверно. Они находятся в стеке, если вы определяете их внутри функции и в куче, если вы создаете их с помощью new. Обратите внимание, что с Java, если вы используете примитив int, он обычно основан на стеке и Integer объекты основаны на куче, но это более продвинутый нюанс Java за пределами базовых знаний о стеке.

Вы можете получить доступ к int a, b, c; всем тем же областям, потому что это пространство для всех трех переменных в пределах этой области стека функций. Когда функция возвращается, эти переменные очищаются, когда стек перемещается обратно. До этого момента все 3 присутствуют, потому что весь блок видимости сразу является частью структуры FILO стека и будет сохраняться до тех пор, пока вы не вернетесь.

1

Существует много ответов на этот вопрос, в зависимости от того, в какой среде вы работаете. Разумеется, вы не должны приравнивать процессорный стек, как и в (с инструкциями POP и PUSH) с стеком (или более правильно stackframe), используемый чем-то вроде интерпретатора python или.чистая среда

Но короткий ответ верх стека просто место в памяти, так что вы просто использовать смещение

если ты Нажимаем, б, в

поэтому адрес Ь будет адресом стека - 4.