2012-03-22 4 views
1

Im принимает класс сборки, и мы в настоящее время узнаем о стеке. Из того, что я узнал, все, что попало в стек, должно в конечном итоге быть вытолкнуто (очистка стека). Почему нам абсолютно необходимо очистить стек? Я читал, что это предотвращает утечку памяти, не так ли?Почему мы должны очищать стек?

Большое спасибо

ответ

2

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

3

Существует только определенное количество стека для данного потока выполнения.

Его целью является временное хранение данных, необходимых при вызове функции (например, адрес возврата и параметры, переданные функции).

Если вы делаете не, очистите стек, когда ваша функция выйдет, вы в конечном итоге закончите пространство стека.

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

2

Если вы не очистите стек, как вызывающая функция найдет его переменные? Вызов будет выполняться, выполнять некоторые операции со своими переменными в стеке, а затем возвращаться к вызывающему абоненту - теперь, что может сделать вызывающий, если указатель стека изменился? Как он может восстановить его, чтобы выяснить, где его собственные переменные стека? Единственный ответ - очистить стек - неважно, кто это делает (вызываемый или вызывающий), но кто-то должен.

Термин «утечка памяти» обычно относится к потере указателя на распределение динамической памяти, так что вы не можете выделить free().

+0

«утечка памяти» обычно означает потерю указателя, потому что стек фактически очищается (компилятор принудительно). Если бы пользователь мог очистить стек (как и при сборке), то на самом деле можно было бы также утечить стек стека, и мы бы действительно говорили о «утечке памяти стека» и «утечке памяти кучи». –

2

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

RET/RTS (или любой другой возвращаемый синтаксис, если он используется для вашего процессора) просто вытаскивает адрес возврата из стека и устанавливает на этот адрес ПК, ProgramCounter.

Если функция помещает дополнительные переменные в стек, но не удаляет их, RET вернет неправильное значение и вернется к неправильному адресу, вызывая все виды нечетного поведения и/исключений/ловушек.

Ошибки, вызванные такого рода поведение может стать очень трудным для отладки, особенно если они не виню immediatley

1

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

Поскольку указатель стека в сборке обычно является регистром, это своего рода глобальная переменная. Если в конце функции указатель стека не установлен в нужное место («очистка стека»), может произойти множество плохих вещей. Система может вернуться к неправильному адресу, вызывающий может вывести неправильное возвращаемое значение, может быть переполнение стека, переполнение и т. Д.

+0

@artjomb. У меня возникли проблемы с поиском того, что не так звездно в этой ссылке после выполнения 20 запросов на изменение. Я получил несколько очевидных отклонений, но некоторые из них были испытаниями. Является ли ваше мета-сообщение точным? – Fuhrmanator

+0

@ArtjomB. Спасибо за ссылки. Я узнал, что изменения кода не допускаются (имеет смысл) и что улучшения грамматики являются субъективными! Счастливой Пасхи. – Fuhrmanator

+0

Что не так с тем, чтобы вести запись об этом обсуждении? – Fuhrmanator

1

Каждая функция может использовать стек, даже если некоторые Dont вы получите вложенности вызовов функций в программах одного() вызывает два() два вызова три() и т.д.

Таким образом, если функция имеет один местный переменные A, B, C в стеке, тогда он вызывает два, два имеют две переменные, которые используют E и F в стеке. Затем три имеют G и H в стеке. Если вы не восстановите указатель стека туда, где он был, когда три введены, когда вы вернетесь к двум, он будет думать, что он обращается к E и F, но вместо этого будет обращаться к G и H или к чему-то еще в зависимости от фрейма стека для трех().

Вы не получаете утечку памяти, вы получаете краху. Иногда вам повезло и выжить, это может быть характер кода для этих функций, но в целом это вызовет ваш скомпилированный код для функций более высокого уровня, которые заставили вас потерпеть неудачу.

Теперь это утечка памяти как в том смысле, что одна функция уничтожает кого-то elses ram, конечно.

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