стек против стека и куча против кучи

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

Но я не понимаю, что такое стек и что такое куча.

Стек - это место в ОЗУ, где хранится память, если в ней не хватает места, происходит переполнение стека. Объекты хранятся здесь по умолчанию, он перераспределяет память, когда объекты выходят за пределы области видимости, и это происходит быстрее.

Куча - это место в ОЗУ, где хранится память, если в ней не хватает места, ОС назначит ей больше. Чтобы объект был сохранен в куче, он должен быть объявлен с помощью оператора new, и будет освобожден только в том случае, если это будет сказано. Могут возникнуть проблемы с фрагментацией, он медленнее, чем стек, и лучше обрабатывает большие объемы памяти.

Но что такое стек и что такое куча? так ли хранится память? например статический массив или статический вектор - это тип стека, а динамический массив, связанный список - тип кучи?

Спасибо вам всем!


person Jwags    schedule 06.05.2014    source источник
comment
I know what the Stack is and what the Heap is, but I'm confused on what a stack is and what a heap is. А?   -  person Rick S    schedule 07.05.2014
comment
Стек и куча - это общие концепции. В языках на основе C стек и куча являются отдельными объектами: стек - это стек выполнения, который управляет вызовом / возвратом, автоматическим хранением переменных и т. Д., А куча - это то, где вы malloc или new части хранилища. Могут быть другие (определяемые пользователем) стеки и кучи, которые управляют совершенно другими задачами.   -  person Hot Licks    schedule 07.05.2014
comment
comment
Не путайте абстрактные типы данных (ADT) с конкретной реализацией. концепции определенного языка (которые не имеют прямого отношения к ADT).   -  person user2864740    schedule 07.05.2014
comment
..и, конечно же, никакой этой информации в Google нет.   -  person Martin James    schedule 07.05.2014
comment
Этот вопрос кажется не по теме, потому что он о том, чтобы извергать свободно доступную информацию.   -  person Martin James    schedule 07.05.2014


Ответы (5)


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

Сравните их со стеком и кучей структурами данных.

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

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

Кстати, имейте в виду, что «стек» или «куча» или любая из структур данных стека / кучи уникальны для любого данного языка программирования, но являются просто концепциями в области информатики.

person Mr. Llama    schedule 06.05.2014
comment
Это конкретное использование общего термина «куча». У вас может быть куча дескрипторов файлов, например, которая не управляется как граф. - person Hot Licks; 07.05.2014
comment
@HotLicks - В этом случае мы будем использовать определение словаря, а не компьютерных наук. - person Mr. Llama; 07.05.2014
comment
Итак, вы утверждаете, что ЕДИНСТВЕННОЕ исключение из использования термина «куча» для представления графа - это куча C / C ++ / Java ??? - person Hot Licks; 07.05.2014
comment
Возможно, мне следует быть более конкретным: в контексте информатики куча - это структура данных древовидного типа, которая удовлетворяет свойству кучи (где значение каждого узла меньше, чем его родительское значение). Было бы неверно называть все остальное в информатике кучей. Например, набор дескрипторов файлов не кучи, потому что он 1) не является древовидной структурой и 2) не удовлетворяет свойству кучи. - person Mr. Llama; 07.05.2014
comment
@HotLicks - Верно, поэтому, вероятно, лучше называть его пулом памяти или чем-то подобным. :П - person Mr. Llama; 07.05.2014
comment
Ну куча чего, конечно. Всегда приятно произвольно переопределить термины, которые использовались в течение 50 лет. - person Hot Licks; 07.05.2014

Я не буду вдаваться в виртуальную память (прочтите об этом, если хотите), поэтому давайте упростим и скажем, что у вас есть ОЗУ определенного размера.

У вас есть код со статическими инициализированными данными, с некоторыми статическими неинициализированными данными (статические в C ++ означают такие же, как глобальные переменные). У тебя есть код.

Когда вы что-то компилируете, компилятор (и компоновщик) организует и переводит ваш код в машинный код (байтовый код, единицы и нули) следующим образом:

Двоичный файл (и объектные файлы) организован в сегменты (части ОЗУ).

Сначала у вас есть сегмент ДАННЫХ. Это сегмент, содержащий значения инициализированных переменных. поэтому, если у u есть переменные, то есть int a=3, b = 4, они перейдут в сегмент DATA (4 байта ОЗУ, содержащие 00000003h, и другие 4 байта, содержащие 000000004h, шестнадцатеричное представление). Они хранятся последовательно.

Тогда у вас есть сегмент кода. Весь ваш код переводится в машинный код (единицы и нули) и сохраняется в этом сегменте последовательно.

Тогда у вас есть сегмент BSS. Идут неинициализированные глобальные вары (все статические вары, которые не были инициализированы).

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

И у вас есть сегмент HEAP. Это часть ОЗУ (размер также определяется ОС), где объекты и данные хранятся с помощью оператора new.

Затем все сегменты складываются один за другим DATA, CODE, BSS, STACK, HEAP. Есть и другие сегменты, но они здесь не интересны и загружаются в оперативную память операционной системой. В двоичном файле также есть заголовки, содержащие информацию о том, с какого места (адреса в памяти) начинается ваш код.

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

person Nenad    schedule 06.05.2014
comment
Какие? вы имеете в виду, что мне не разрешено выполнять код в ПЗУ? О, Боже. Мне придется отбросить много работы и начать все сначала. - person Dale Wilson; 07.05.2014
comment
Нет, вы выполняете код из ПЗУ, но ПЗУ используется для выполнения кода при запуске компьютера. Вы нажимаете кнопку POWER, комп включается, начинает чтение с фиксированного адреса (этот адрес является адресом ПЗУ). Есть небольшой код, который выполняет следующие действия: копирует некоторый код из ПЗУ в ОЗУ, продолжает выполнение скопированного кода из ОЗУ, делает что-то, заглядывает в загрузочный сектор жесткого диска и копирует загрузочный файл ОС в ОЗУ, выполняет его и запускает ОС. После этого вам не нужно запускать ПЗУ, вы дважды щелкаете файл для запуска, загрузчик загружает его в ПЗУ и выполняет. - person Nenad; 07.05.2014
comment
Я хочу сказать, что ваш ответ неточен (он говорит, что все выполняемое загружается в оперативную память). Неправда. Ваш ответ также очень специфичен для одной машинной архитектуры (по общему признанию, общей) и содержит множество деталей, которые на самом деле не касаются вопроса, на который вы отвечали. - person Dale Wilson; 07.05.2014
comment
Да, я имел в виду, что нельзя загрузить в ROM. :) Детали есть, чтобы парень мог понять общую картину. Другие ребята рассказали ему, что такое стек и куча, а я объяснил предысторию (упрощенно). - person Nenad; 07.05.2014

Когда речь идет конкретно о модели памяти C ++, куча и стек относятся к областям памяти. Это легко спутать со структурой данных стека и структурой данных кучи. Однако это отдельные понятия.

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

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

person David S.    schedule 06.05.2014

Техническое определение «стека» - это структура данных «последним вошел - первым ушел» (LIFO), в которой данные вставляются и снимаются сверху. Как и в случае со стопкой пластин в реальном мире, вы не будете вытаскивать одну из середины или снизу, вы [обычно] не извлекаете данные из середины или нижней части стека структур данных. Когда кто-то говорит о стеке с точки зрения программирования, это может часто (но не всегда) иметь в виду аппаратный стек, который управляется регистром указателя стека в ЦП.

Что касается «кучи», это обычно становится гораздо более расплывчатым с точки зрения определения, с которым каждый может согласиться. Лучшее определение, вероятно, - «большой объем свободной памяти, из которой выделяется пространство для управления динамической памятью». Другими словами, когда вам нужна новая память, будь то для массива или объекта, созданного с помощью оператора new, она поступает из кучи, которую ОС зарезервировала для вашей программы. Это «куча» из точки обзора вашей программы, но просто «куча» из точки обзора ОС.

person stix    schedule 06.05.2014
comment
Куча может быть набором похожих объектов, которые не являются просто фрагментами свободного хранилища. - person Hot Licks; 07.05.2014
comment
Это правда, но это не тот контекст, в котором работает OP. Возможно, имеет смысл называть кучу OP кучей памяти. - person stix; 07.05.2014

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

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

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

Re: Ваш вопрос о стеке и стеке: когда вы используете несколько потоков, каждый поток имеет отдельный стек, так что каждый поток может входить и выходить из функций / методов независимо. Большинство однопоточных программ имеют только один стек: «стек» в общей терминологии.

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

person Dale Wilson    schedule 06.05.2014