Стек: Стек используется как своего рода временная блокнотная книга для блока кода, который в данный момент выполняется, и любого блока, который называется текущим, и любого блока, который называется этим, и так далее. При выходе из текущего блока локальные переменные, которые он использовал, забываются. Как видно из названия, стек используется по принципу «последним пришел - первым вышел».
Одно из наиболее важных применений стека - отслеживать текущую цепочку вызовов. Когда одна функция вызывает другую, вызывающая сторона помещает адрес следующей инструкции (адрес возврата) в стек. При выходе из каждой функции она извлекает из стека адрес возврата вызывающей стороны и продолжает выполнение кода, начиная с этого адреса. Он также используется для передачи параметров функции и возвращаемых значений между вызывающим и вызываемым объектами.
Куча. Куча отличается - в ней нет определенного порядка. Если вы хотите выделить память в блоке кода и разместить эту карту памяти за концом блока, вы выделяете ее в куче. Конечно, вам также необходимо где-нибудь сохранить указатель / ссылку на него, чтобы другой код мог найти эту память; большинство языков предоставляют для этого приспособление.
Скорость: разница в скорости не связана с каким-либо свойством самой памяти - как вы говорите в своем вопросе, и стек, и куча обычно занимают одну и ту же физическую память. Выделение места в стеке происходит быстро из-за природы стека LIFO: если вы поместите что-то в стек, это может закончиться только в одном месте. Напротив, выделение блока в куче требует поиска достаточно большой непрерывной свободной области в памяти. Выделение стека может происходить так же быстро, как одна инструкция; для выделения кучи требуется вызов функции выделения памяти, такой как malloc()
.
Статический или динамический: распределение памяти в куче является динамическим - следует ли выделять блок, и размер блока может быть определен в соответствии с входными данными, которые программа получает во время работы. При необходимости можно даже изменить размер областей памяти, выделенных в куче. Также возможно динамически выделять память в стеке (см. Функцию стандартной библиотеки C alloca()
), но эта память будет потеряна, как только текущая функция завершится. Выделение стека обычно является статическим - компилятор определяет, сколько места необходимо для (не регистровых) параметров, возвращаемых данных и локальных переменных, и генерирует код, чтобы зарезервировать необходимое пространство в стеке при вызове функции.
Пример. Представьте, что вы создаете текстовый процессор. Вы не можете заранее знать, какого размера будет документ или сколько документов будет использоваться одновременно. В то же время вы хотите, чтобы документы пользователя оставались в памяти до тех пор, пока пользователь хочет держать их открытыми. Если вы попытаетесь выделить память для документов в стеке, вам будет сложно открыть более одного документа одновременно, и вам потребуется создать единую функцию, которая создает, редактирует, сохраняет и закрывает документ. Выделение пространства в куче позволяет вам создавать столько документов, сколько вам нужно, каждый из которых имеет размер, соответствующий содержащимся в нем данным, и не связывать время жизни документов со временем жизни какой-либо конкретной функции.
Резюме. В двух словах, стек хранит значения переменных (иногда вместо них используются регистры), а куча используется для выделения памяти, которая будет использоваться по истечении срока жизни текущего блока.
person
Caleb
schedule
17.11.2011