2012-04-17 2 views
2

Что такое память кучи?Память кучи в программировании на языке С

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

ответ

2

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

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

Вы можете посмотреть на это для получения дополнительной информации:

http://computer.howstuffworks.com/c28.htm

+0

Кто-нибудь? Мне просто интересно узнать, какую ценность извлечь из этого, потому что это похоже на совершенно недействительный ответ. Возможно, вы можете уточнить ... вы говорите, что 1/когда какая-то память используется программой, она находится в куче? Или вы говорите 2 /, как только программа закончится с памятью, она попадает в кучу? Любой из них * неверен *. Включает ли это память регистров и память на вращающемся жестком диске? – Sebivor

+0

Кроме того, это пример очень плохого ресурса для обучения C. Если вам нужно руководство для ссылки, это [руководство POSIX 'malloc'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions /malloc.html), который вы заметите, не ссылается на термин * heap *, так как люди, которые написали вашу * кучу *, понимают (как и должны), что это не обязательно * heap *; это * книжное пространство *. – Sebivor

+0

@Sebivor - память, которая не используется приложением, - это то, что я называл кучей. Таким образом, у вас есть все распределения, которые являются частью запуска приложения, а память, доступная для malloc, - это куча. –

7

кучного является частью адресного пространства вашего процесса. Кучу можно выращивать или сокращать; вы управляете им, позвонив по телефону brk(2) или sbrk(2). Это на самом деле то, что делает malloc(3).

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

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

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

+0

«Выделение из кучи более удобно, чем выделение памяти в стеке, потому что оно сохраняется после возврата вызывающей процедуры» - логика здесь неполна и недействительна; он должен больше походить на то, что «Выделение из кучи более удобно, чем выделение в стеке, потому что [мы используем память, которая сохраняется после возврата вызывающей подпрограммы, и] она сохраняется после возвращения вызывающей процедуры». Теперь вы должны увидеть одно, что не так с этим; во многих случаях нам нужна память с такой настойчивостью, а вызов «бесплатно», когда это не нужно, - не более удобно *, вопреки утверждению. – Sebivor

+0

Кроме того, даже если вы используете память, для которой требуется время жизни, отличное от функции немедленной работы, у вас есть еще две возможности: ** 1/предпочтительно (и это должно быть вашей целью большую часть времени), вы должны принять аргумент, указывающий на объект, и этот объект может иметь * любую * продолжительность хранения; вызывающий абонент решает, требуется ли «malloc» (так работают «strcat», «sprintf» и т. д.) ** и 2/существуют две другие длительности хранения, которые вы не упомянули (статические и зависящие от потока), и не указано, прикреплены ли они к * куче * или * стеку * (или * регистры *, fwiw) ... – Sebivor

+0

Существует даже часто третий вариант, который является восходящим потоком, где-то вы удаляете зависимость на вариативные массивы и сосредоточиться на обработке фиксированных данных побайтно (без сохранения копии) по мере их получения из источника. Фактически, вы можете почти ссылаться на обычную файловую систему, как на другую форму * продолжительности хранения *, за исключением того, что стандарт C не определяет файлы очень строго. – Sebivor

2

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

О, и память кучи требует использования указателей.

Резюме кучи:

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

кредит craftofcoding

+0

Полный ответ на вопрос; Однако у меня есть несколько предложений. Для начала вы, вероятно, хотели написать «Объекты, созданные в куче, доступны в любом месте программы». а не «Переменные, созданные в куче, доступны в любом месте программы». Во-вторых, хотя программист, возможно, косвенно манипулирует кучей, вызывая «malloc», способность программиста модифицировать такую ​​базовую структуру не является * немного безграничной *; если вы заходите слишком далеко, вы рискуете в * неопределенное поведение *, в котором вы нарушили правила C. – Sebivor

+0

Нарушение правил в C может показаться так, как будто вы пересекли границу. На самом деле, например, это касается переполнения буфера. Иногда вы получаете переполнение, которое работает ... в других случаях вы этого не делаете. Правила нарушения не имеют четко определенных последствий, а границы для манипулирования этой базовой структурой без вызова UB несколько связаны: вы можете добавлять записи, вызывая 'malloc', изменять записи, используя' realloc', и удалять записи, используя 'free'. – Sebivor

+0

Нарушение правил в C может выглядеть так, как если бы вы пересекли границу. На самом деле, например, это касается переполнения буфера. Иногда вы получаете переполнение, которое работает ... в других случаях вы этого не делаете. Правила нарушения не имеют четко определенных последствий, а границы для манипуляции с этой базовой структурой несколько связаны: вы можете добавлять записи, вызывая 'malloc', изменять записи с помощью' realloc' и удалять записи, используя 'free'. – Sebivor

0

Читая это, это на самом деле за рамки сферы C. C не определяет, что есть куча за malloc; его можно так же легко назвать связанным списком ; вы просто называете это кучей по соглашению.

Какие стандартные гарантии, что malloc либо возвращает указатель на объект, который имеет динамическую длительность хранения, и ваша куча только один тип структуры данных, которая облегчает предоставление такого срока хранения. Это общий выбор. Тем не менее, сами разработчики, которые написали свою кучу признали, что это не может быть кучей, и поэтому вы не увидите никаких ссылок термина кучного в the POSIX malloc manual, например.

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

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

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

+0

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

+0

@DaveNewton Правда, это. Подумайте об этом, он используется на смарт-картах Java. Виноват! Та :) – Sebivor

Смежные вопросы