2015-09-27 4 views
0

Я прочитал в книге:Почему память не равна нулю из malloc?

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

Итак, я смущен, почему память из кучи не инициализируется нулем. Чтобы быть более точным, я имею в виду кусок памяти, возвращаемый malloc.

+1

Это совсем другая «куча». На самом деле стандарт C не имеет понятия «куча». Слово означает много разных вещей в зависимости от контекста. –

+9

Потому что этого не требуется. Для этого есть 'calloc'. –

+1

Зачем это было? Нет никакого преимущества, и удар производительности может быть значительным. Если вы хотите, чтобы динамическая память была инициализирована до нуля, используйте «calloc (3)». –

ответ

1

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

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

На этой типичной платформе, когда задача запрашивает операционную систему для большей памяти (путем системного вызова ядра, например, с помощью brk system call в традиционных Unix-системах), ядро ​​операционной системы обнаруживает некоторую физическую память, не используется какой-либо другой задачей, помещает его во внутренние структуры данных как находящиеся в использовании и ссылается на них в карте памяти задачи в конце последовательного сегмента виртуальных адресов, называемых BSS или кучей. Кроме того, эта память обнуляется, так что задача не будет читать некоторые данные, оставленные другой задачей.

Функция malloc работает, выделяя куски области кучи. Он полностью работает внутри кучи задачи. Это только делает системный вызов, чтобы получить больше памяти, если куча заполнена. На большинстве платформ функция malloc не перезаписывает память, которую она выделяет, для производительности. Поэтому, когда блок памяти используется впервые после того, как он был получен из операционной системы, он будет обнулен. Но если память уже использовалась внутри задачи, потому что она получена с помощью malloc, затем освобождается с помощью free и повторно используется другим malloc, тогда память будет содержать все, что было поставлено перед ней в первый раз.

+0

Только вы понимаете, что я имею в виду. Благодарю. – Gilgamesz

0

Чтобы сократить длинную историю, потому что malloc() не разработан таким образом.

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

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

OTOH, calloc() выполняет нулевую инициализацию выделенной памяти, если вам это нужно.

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