Подтвердить что ты не робот

Память стека против памяти кучи

Возможный дубликат:
Что и где находятся стек и куча

Я программирую на С++, и мне всегда интересно, что такое память стека и память кучи. Все, что я знаю, это когда я называю новое, я получаю память из кучи. Если при создании локальных переменных я получаю память из стека. После некоторых исследований в Интернете наиболее распространенный ответ - это временная память стека, а память кучи постоянна.

Является ли модель памяти стека и кучи концепцией операционной системы или компьютерной архитектуры? Таким образом, некоторые из них могут не следовать модели памяти в стеке и куче или все они следуют за ней?

Память стека и кучи - это абстракция по модели памяти виртуальной памяти (которая может менять память между диском и оперативной памятью). Таким образом, как стек, так и память кучи физически могут быть ОЗУ или диском? Тогда в чем причина, когда распределение кучи кажется медленнее, чем совпадение стека?

Кроме того, основная программа будет выполняться в стеке или куче?

Кроме того, что произойдет, если процесс закончится из памяти стека или выделенной памяти кучи?

Спасибо

4b9b3361

Ответ 1

Память стека - это, в частности, область памяти, доступная через регистр стека процессора. Stack использовался как способ реализации шаблона кода "Jump-Subroutine" - "Return" на языке ассемблера, а также в качестве средства реализации обработки прерываний на аппаратном уровне. Например, во время прерывания Stack использовался для хранения различных регистров CPU, включая Status (который указывает результаты операции) и счетчик программ (где был CPU в программе, когда произошло прерывание).

Память стека очень важна для обычного дизайна ЦП. Скорость его распределения/освобождения происходит быстро, потому что это строго последний дизайн. Это простой вопрос операции перемещения и операции уменьшения/увеличения в регистре Stack.

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

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

Ответ 2

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

Стек похож на класс std:: stack, вы нажимаете на него параметры, а затем вызываете функцию. Затем функция знает, какие параметры она ожидает, может быть найдена в конце стека. Точно так же функция может подтолкнуть локальных жителей к стеку и выскочить из него перед возвратом из функции. (оптимизация caveat-компилятора и соглашения о вызовах - все это не так просто)

Стек лучше всего понять с низкого уровня, и я бы рекомендовал эту ссылку Art of Assembly - Передача параметров в стеке. Редко, если когда-нибудь вы рассмотрите какую-либо ручную манипуляцию стеком из С++.

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

Память кучи очень важна, как говорит rskar. Вообще говоря, объекты С++, выделенные новым, или блоки памяти, выделенные с помощью malloc, попадают в кучу. Память кучи почти всегда должна быть освобождена вручную, хотя вам следует использовать класс интеллектуальных указателей или аналогичный, чтобы избежать необходимости помнить об этом. Запуск из памяти кучи может (будет?) Привести к std:: bad_alloc.

Ответ 3

Это абстракция языка - на некоторых языках есть как одна, так и некоторая.

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