Что и где находится стек и куча?

Почему бы не объединить random.uniform со списком?

>>> def random_floats(low, high, size):
...    return [random.uniform(low, high) for _ in xrange(size)]
... 
>>> random_floats(0.5, 2.8, 5)
[2.366910411506704, 1.878800401620107, 1.0145196974227986, 2.332600336488709, 1.945869474662082]

7754
задан RajeshKdev 10 April 2019 в 06:03
поделиться

12 ответов

Стек является памятью, отложенной как пространство царапины для потока выполнения. Когда функция вызвана, блок резервируется на вершине стека для локальных переменных и некоторых бухгалтерских данных. Когда та функция возвращается, блок становится неиспользованным и может использоваться в следующий раз, когда функция вызвана. Стек всегда резервируется в LIFO (метод "последним пришел - первым вышел") порядок; последний раз зарезервированный блок всегда является следующим блоком, который будет освобожден. Это делает действительно простым отслеживать стек; освобождение блока от стека является не чем иным как корректировкой одного указателя.

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

Каждый поток получает стек, в то время как существует обычно только одна "куча" для приложения (хотя это не редко, чтобы иметь несколько "кучи" для различных типов выделения).

Для ответа на вопросы непосредственно:

, До какой степени ими управляют время выполнения языка или ОС?

ОС выделяет стек для каждого потока системного уровня, когда поток создается. Обычно ОС называет время выполнения языка для выделения "кучи" для приложения.

, Каков их объем?

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

, Что определяет размер каждого из них?

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

, Что делает один быстрее?

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

А очищают демонстрацию:
Источник изображения: vikashazrati.wordpress.com

5751
ответ дан Ates Goral 10 April 2019 в 16:03
поделиться

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

"куча" является частью памяти, которая дана приложению операционной системой, обычно через syscall как malloc. На современных Ose эта память является рядом страниц, к которым только обработка вызовов имеет доступ.

размер стека определяется во времени выполнения и обычно не растет после запусков программы. В программе C стек должен быть достаточно большим для содержания каждой переменной, объявленной в каждой функции. "Куча" вырастет динамично по мере необходимости, но ОС в конечном счете выполняет вызов (это будет часто выращивать "кучу" больше, чем значение, которое требует malloc, так, чтобы по крайней мере некоторое будущее mallocs не должно было возвращаться к ядру для получения большей памяти. Это поведение часто настраиваемо)

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

112
ответ дан Daniel Papasian 10 April 2019 в 16:03
поделиться
  • 1
    I' m не 100%-й верный that' s верный: у Меня есть ToggleButton, который связывает IsChecked с bool. Если в методе set я вызываю его ко лжи и уведомляю относительно изменения свойства, это правильно остается непроверенным. Это предполагает, что обращает внимание на измененные уведомления дальнейшего свойства.? – Kieren Johnstone 18 October 2011 в 20:19

Стек:

  • Сохраненный в оперативной памяти точно так же, как "куча".
  • Переменные, созданные на стеке, выйдут из объема и автоматически освобождены.
  • Намного быстрее для выделения по сравнению с переменными на "куче".
  • Реализованный с фактической структурой данных стека.
  • Хранит локальные данные, обратные адреса, используемые для передачи параметров.
  • Может иметь переполнение стека, когда слишком много стека используется (главным образом от бесконечной или слишком глубокой рекурсии, очень больших выделений).
  • Данные, созданные на стеке, могут использоваться без указателей.
  • Вы использовали бы стек, если Вы знаете точно, сколько данных необходимо выделить, прежде чем время компиляции и это не являются слишком большими.
  • Обычно имеет максимальный размер, уже определил, когда Ваша программа запускается.

"куча":

  • Сохраненный в оперативной памяти точно так же, как стек.
  • В C++, переменные на "куче" должны быть уничтожены вручную и никогда не падать из объема. Данные освобождены с delete, delete[], или free.
  • Медленнее для выделения по сравнению с переменными на стеке.
  • Используемый по требованию для выделения блока данных для использования программой.
  • Может иметь фрагментацию, когда существует много выделений и освобождения.
  • В C++ или C, на данные, созданные на "куче", укажут указатели и выделят с new или malloc соответственно.
  • Может иметь отказы выделения, если слишком большой буфера, требуется быть выделенным.
  • Вы использовали бы "кучу", если Вы не знаете точно, в каком количестве данных Вы будете нуждаться во время выполнения или если необходимо выделить много данных.
  • Ответственный за утечки памяти.

Пример:

int foo()
{
  char *pBuffer; //<--nothing allocated yet (excluding the pointer itself, which is allocated here on the stack).
  bool b = true; // Allocated on the stack.
  if(b)
  {
    //Create 500 bytes on the stack
    char buffer[500];

    //Create 500 bytes on the heap
    pBuffer = new char[500];

   }//<-- buffer is deallocated here, pBuffer is not
}//<--- oops there's a memory leak, I should have called delete[] pBuffer;
2264
ответ дан Rob 10 April 2019 в 16:03
поделиться

Стек , Когда Вы вызываете функцию, аргументы той функции плюс некоторые другие издержки помещаются на стек. Некоторая информация (такой как, где пойти на возврат) также хранится там. Когда Вы объявляете переменную в своей функции, та переменная также выделяется на стеке.

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

"куча" "куча" является родовым названием для того, куда Вы помещаете данные, которые Вы создаете на лету. Если Вы не будете знать, сколько космических кораблей Ваша программа собирается создать, Вы, вероятно, будете использовать новое (или malloc или эквивалентный) оператор для создания каждого космического корабля. Это выделение собирается слоняться поблизости некоторое время, таким образом, вероятно, что мы освободим вещи в другом порядке, чем мы создали их.

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

Реализация Реализация и стека и "кучи" обычно до времени выполнения / ОС. Часто игры и другие приложения, которые являются очень важной производительностью, создают свои собственные решения для памяти, которые захватывают большой блок памяти от "кучи" и затем подают ее внутренне, чтобы не полагаться на ОС для памяти.

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

Физическое местоположение в памяти Это менее релевантно, чем Вы думаете из-за технологии, названной Виртуальная память , который заставляет Вашу программу думать, что у Вас есть доступ к определенному адресу, где физические данные где-то в другом месте (даже на жестком диске!). Адреса, которые Вы получаете для стека, находятся в увеличивающемся порядке, поскольку Ваше дерево вызова становится глубже. Адреса для "кучи" непредсказуемы (т.е. конкретная реализация) и откровенно не важные.

201
ответ дан Tom Leys 10 April 2019 в 16:03
поделиться

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

  1. Стек и "куча" не должны быть исключительными. Общая ситуация, в которой у Вас есть больше чем один стек, состоит в том, если у Вас есть больше чем один поток в процессе. В этом случае каждый поток имеет свой собственный стек. У Вас может также быть больше чем одна "куча", например, некоторые конфигурации DLL могут привести к другому DLLs, выделяющему от различной "кучи", который является, почему это обычно - плохая идея освободить память, выделенную другой библиотекой.

  2. В C можно извлечь пользу из выделения переменной длины с помощью alloca, который выделяет на стеке, в противоположность выделению, которое выделяет на "куче". Эта память не переживет Ваш оператор возврата, но это полезно для буфера царапины.

  3. Создание огромного временного буфера в Windows, из которого Вы не используете большую часть из, не является бесплатным. Это вызвано тем, что компилятор генерирует цикл датчика стека, который называют каждый раз, когда Ваша функция вводится, чтобы удостовериться, что стек существует (потому что Windows использует единственную защитную страницу в конце Вашего стека для обнаружения, когда это должно вырастить стек. При доступе к памяти больше чем одна страница от конца стека, Вы откажете). Пример:

void myfunction()
{
   char big[10000000];
   // Do something that only uses for first 1K of big 99% of the time.
}
164
ответ дан Peter Mortensen 10 April 2019 в 16:03
поделиться

Я думаю, что многие другие люди дали Вам главным образом корректные ответы по этому вопросу.

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

111
ответ дан 10 April 2019 в 16:03
поделиться
  • 1
    То, когда я попробовал то же самое своим ComboBox, связывающим его, будет всегда оставаться на значении, которое было выбрано пользователем, даже после тех шагов. – RandomEngy 19 October 2011 в 02:19

Другие непосредственно ответили на Ваш вопрос, но при попытке понять стек и "кучу", я думаю, что полезно рассмотреть расположение памяти традиционного процесса UNIX (без потоков и mmap() - базирующиеся средства выделения). веб-страница Глоссария управления памятью имеет схему этого расположения памяти.

стек и "куча" традиционно расположены в противоположных концах виртуального адресного пространства процесса. Стек растет автоматически при доступе, до размера, установленного ядром (который может быть скорректирован с setrlimit(RLIMIT_STACK, ...)). "Куча" растет, когда средство выделения памяти вызывает brk() или sbrk() системный вызов, отображая больше страниц физической памяти в виртуальное адресное пространство процесса.

В системах без виртуальной памяти, таких как некоторые встроенные системы, тот же базовый макет часто применяется, кроме стека и "кучи" фиксируются в размере. Однако в других встроенных системах (таких как те, которые на основе Микрочипа микроконтроллерами PIC), стопка программы является отдельным блоком памяти, которая не адресуема инструкциями по перемещению данных, и может только быть изменена или считана косвенно через инструкции по процессу выполнения программы (вызов, возвратитесь, и т.д.). Другая архитектура, такая как процессоры Intel Itanium, имеет несколько стеков . В этом смысле стек является элементом архитектуры ЦП.

130
ответ дан EthanP 10 April 2019 в 16:03
поделиться

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

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

В "классической" системной RAM был размечен таким образом, что указатель вершины стека начался у основания памяти, указатель "кучи", начатый наверху, и они выросли друг к другу. Если они накладываются, Вы вне RAM. Это не работает с современными многопоточными Ose все же. Каждый поток должен иметь свой собственный стек, и они могут быть созданы динамично.

86
ответ дан T.E.D. 10 April 2019 в 16:03
поделиться

Можно сделать некоторые интересные вещи со стеком. Например, у Вас есть функции как alloca (предполагающий, что можно закончить обильные предупреждения относительно его использования), который является формой malloc, который конкретно использует стек, не "кучу", для памяти.

Тем не менее стековые ошибки памяти являются некоторыми худшими, которые я испытал. Если Вы используете память "кучи", и Вы переступаете через границы своего выделенного блока, у Вас есть достойный шанс инициирования отказа сегментов. (Не 100%: Ваш блок может быть случайно непрерывным с другим, что Вы ранее выделили.), Но так как переменные, созданные на стеке, всегда непрерывны друг с другом, писание за пределы может изменить значение другой переменной. Я узнал, что каждый раз, когда я чувствую, что моя программа прекратила подчиняться законам логики, это - вероятно, переполнение буфера.

89
ответ дан Peter 10 April 2019 в 16:03
поделиться

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

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

    Stack like a stack of papers

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

  • В "куче", нет никакого особого порядка к способу, которым помещаются объекты. Можно достигнуть в и удалить объекты в любом порядке, потому что нет никакого ясного 'главного' объекта.

    Heap like a heap of licorice allsorts

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

Эти изображения должны сделать довольно хорошее задание описания двух способов выделить и освободить память в стеке и "куче". Конфетка!

  • , До какой степени ими управляют время выполнения языка или ОС?

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

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

  • , Каков их объем?

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

  • , Что определяет размер каждого из них?

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

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

  • , Что делает один быстрее?

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

1335
ответ дан thomasrutter 10 April 2019 в 16:03
поделиться
  • 1
    +1 для получения информации о блоке развертывания – mukund 18 February 2013 в 05:15

От WikiAnwser.

Стек

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

Эта цепочка приостановленных вызовов функции является стеком, потому что элементы в стеке (вызовы функции) зависят друг от друга.

Стек важен для рассмотрения в выполнении потока и обработке исключений.

"Куча"

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

81
ответ дан 22 November 2019 в 19:37
поделиться

(Я переместил этот ответ из другого вопроса, который был более или менее похож на этот.)

Ответ на ваш вопрос зависит от реализации и может варьироваться в зависимости от компилятора и архитектуры процессора. . Однако здесь приводится упрощенное объяснение.

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

Куча

  • Куча содержит связанный список используемых и свободных блоков. Новые выделения в куче ( new или malloc ) выполняются путем создания подходящего блока из одного из свободных блоков. Это требует обновления списка блоков в куче. Эта метаинформация о блоках в куче также сохраняется в куче, часто в небольшой области прямо перед каждым блоком.
  • По мере роста кучи новые блоки часто распределяются от более низких адресов к более высоким адреса. Таким образом, вы можете думать о куче как о куче блоков памяти, размер которой увеличивается по мере выделения памяти. Если куча слишком мала для распределения, размер часто можно увеличить, получив больше памяти из базовой операционной системы.
  • Выделение и освобождение множества небольших блоков может оставить кучу в состоянии, когда между используемыми блоками перемежается множество небольших свободных блоков. Запрос на выделение большого блока может завершиться неудачно, потому что ни один из свободных блоков не является достаточно большим, чтобы удовлетворить запрос на выделение, даже если объединенный размер свободных блоков может быть достаточно большим. Это называется фрагментацией кучи .
  • Когда используемый блок, который находится рядом со свободным блоком, освобождается, новый свободный блок может быть объединен со смежным свободным блоком для создания большего свободного блока, эффективно уменьшающего фрагментацию кучи.

The heap

Стек

  • Стек часто работает в тесном тандеме со специальным регистром на ЦП, который называется указателем стека . Изначально указатель стека указывает на вершину стека (самый высокий адрес в стеке).
  • ЦП имеет специальные инструкции для проталкивания значений в стек и выталкивания их обратно из стека. Каждый push сохраняет значение в текущем местоположении указателя стека и уменьшает указатель стека. pop извлекает значение, на которое указывает указатель стека, а затем увеличивает указатель стека (пусть вас не смущает тот факт, что добавление значения в стек уменьшает указатель стека и удаление значения увеличивает его . Помните, что стек увеличивается до самого низа). Сохраненные и извлеченные значения являются значениями регистров ЦП.
  • Когда функция вызывается, ЦП использует специальные инструкции, которые нажимают текущий указатель инструкции , т.е. адрес кода, выполняющегося в стеке. Затем CPU переходит к функции, устанавливая указатель инструкции на адрес вызываемой функции. Позже, когда функция возвращается, старый указатель инструкции выталкивается из стека, и выполнение возобновляется с кода сразу после вызова функции.
  • Когда функция вводится, указатель стека уменьшается, чтобы выделить больше места на стек для локальных (автоматических) переменных. Если функция имеет одну локальную 32-битную переменную, в стеке выделяются четыре байта. Когда функция возвращается, указатель стека перемещается назад, чтобы освободить выделенную область.
  • Если функция имеет параметры, они помещаются в стек перед вызовом функции. Затем код функции может перемещаться вверх по стеку от текущего указателя стека, чтобы найти эти значения.
  • Вложенные вызовы функций работают как шарм. Каждый новый вызов будет выделять параметры функции, адрес возврата и пространство для локальных переменных, и эти записи активации могут быть сложены для вложенных вызовов и будут раскручиваться правильным образом при возврате функций.
  • Поскольку стек представляет собой ограниченный блок памяти, вы может вызвать переполнение стека , вызвав слишком много вложенных функций и / или выделив слишком много места для локальных переменных. Часто область памяти, используемая для стека, настраивается таким образом, что запись ниже нижнего (самого низкого адреса) стека запускает ловушку или исключение в ЦП. Это исключительное условие затем может быть обнаружено средой выполнения и преобразовано в какое-то исключение переполнения стека.

The stack

Можно ли выделить функцию в куче, а не в стеке?

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

То, как управляется куча, действительно зависит от среды выполнения. C использует malloc , а C ++ использует new , но во многих других языках есть сборка мусора.

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

Как управлять кучей, действительно зависит от среды выполнения. C использует malloc , а C ++ использует new , но во многих других языках есть сборка мусора.

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

Как управлять кучей, действительно зависит от среды выполнения. C использует malloc , а C ++ использует new , но во многих других языках есть сборка мусора.

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

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

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

710
ответ дан 22 November 2019 в 19:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: