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