Malloc() против HeapAlloc()

В чем разница между malloc() и HeapAlloc()? Насколько я понимаю, malloc выделяет память из кучи, как HeapAlloc, правильно?

Так в чем же разница?

Спасибо!

Ответ 1

Вы правы, что оба они выделяют память из кучи. Но есть различия:

  • malloc() является портативным, частью стандарта.
  • HeapAlloc() не является переносимым, это функция Windows API.

Вполне возможно, что в Windows malloc будет реализован поверх HeapAlloc. Я ожидал бы, что malloc будет быстрее, чем HeapAlloc.

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

Для почти всех сценариев кодирования вы должны использовать malloc, а не HeapAlloc. Хотя, поскольку вы отметили свой вопрос С++, я ожидаю, что вы будете использовать new!

Ответ 2

На самом деле функции malloc() (и другие функции кучи времени выполнения C) зависят от модуля, а это означает, что если вы вызываете malloc() в коде из одного модуля (то есть DLL), тогда вы должны вызвать free() в коде кода тот же модуль, или вы могли бы понести некоторые довольно плохие повреждения кучи (и это было хорошо документировано). Используя HeapAlloc() с GetProcessHeap() вместо malloc(), включая перегрузку новых и удаленных операторов, чтобы использовать их, вы можете передавать динамически распределенные объекты между модулями и не беспокоиться о повреждении памяти, если память распределена в коде один модуль и освобожден в коде другого модуля, когда указатель на блок памяти передан во внешний модуль.

Ответ 3

С Visual С++ функция malloc() или оператор new в конечном итоге вызывает HeapAlloc(). Если вы отлаживаете код, вы обнаружите, что функция _heap_alloc_base() (в файле malloc.c) вызывает return HeapAlloc(_crtheap, 0, size), где _crtheap - глобальная куча, созданная с помощью HeapCreate().

Функция HeapAlloc() выполняет хорошую работу, чтобы минимизировать накладные расходы на память, при этом на выделение не менее 8 байт. Самое крупное, что я видел, - 15 байт на выделение, для распределений от 1 байт до 100 000 байт. Более крупные блоки имеют большие накладные расходы, однако, поскольку процент от общего объема выделяемых ресурсов остается менее 2,5% полезной нагрузки.

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

Ответ 4

malloc - это функция в стандартной библиотеке C (а также в стандартной библиотеке С++).

HeapAlloc - это функция Windows API.

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

Приветствия и hth.,

Ответ 5

Кроме того, вы можете обратиться к:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa366705(v=vs.85).aspx

Что означает, что вы можете включить некоторые функции HEAP, которыми управляет распределитель памяти WinApi, например "HeapEnableTerminationOnCorruption".

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

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

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

Ответ 6

Это то, что MS должна сказать об этом: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx

Одна вещь, о которой говорилось выше, заключается в следующем: "Функция malloc имеет недостаток в зависимости от времени выполнения. У нового оператора есть недостаток в том, что он зависит от компилятора и зависит от языка."

Кроме того, "HeapAlloc может быть проинструктирован об увеличении исключения, если невозможно выделить память"

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