В чем разница между malloc() и HeapAlloc()? Насколько я понимаю, malloc выделяет память из кучи, как HeapAlloc, правильно?
Так в чем же разница?
Спасибо!
В чем разница между malloc() и HeapAlloc()? Насколько я понимаю, malloc выделяет память из кучи, как HeapAlloc, правильно?
Так в чем же разница?
Спасибо!
Вы правы, что оба они выделяют память из кучи. Но есть различия:
malloc()
является портативным, частью стандарта.HeapAlloc()
не является переносимым, это функция Windows API.Вполне возможно, что в Windows malloc
будет реализован поверх HeapAlloc
. Я ожидал бы, что malloc
будет быстрее, чем HeapAlloc
.
HeapAlloc
имеет большую гибкость, чем malloc
. В частности, он позволяет указать, какую кучу вы хотите выделить. Это обслуживает несколько куч за каждый процесс.
Для почти всех сценариев кодирования вы должны использовать malloc
, а не HeapAlloc
. Хотя, поскольку вы отметили свой вопрос С++, я ожидаю, что вы будете использовать new
!
На самом деле функции malloc() (и другие функции кучи времени выполнения C) зависят от модуля, а это означает, что если вы вызываете malloc() в коде из одного модуля (то есть DLL), тогда вы должны вызвать free() в коде кода тот же модуль, или вы могли бы понести некоторые довольно плохие повреждения кучи (и это было хорошо документировано). Используя HeapAlloc() с GetProcessHeap() вместо malloc(), включая перегрузку новых и удаленных операторов, чтобы использовать их, вы можете передавать динамически распределенные объекты между модулями и не беспокоиться о повреждении памяти, если память распределена в коде один модуль и освобожден в коде другого модуля, когда указатель на блок памяти передан во внешний модуль.
С 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()
, накладные расходы удивительно низки.
malloc
- это функция в стандартной библиотеке C (а также в стандартной библиотеке С++).
HeapAlloc
- это функция Windows API.
Последний позволяет указать кучу для выделения из нее, что, по моему мнению, может быть полезно для предотвращения сериализации запросов на распределение в разных потоках (обратите внимание на флаг HEAP_NO_SERIALIZE
).
Приветствия и hth.,
Кроме того, вы можете обратиться к:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366705(v=vs.85).aspx
Что означает, что вы можете включить некоторые функции HEAP, которыми управляет распределитель памяти WinApi, например "HeapEnableTerminationOnCorruption".
Как я понимаю, он создает некоторые основные защиты переполнения кучи, которые можно рассматривать как добавленную стоимость для вашего приложения с точки зрения безопасности.
(например, я бы предпочел сбой моего приложения (как владельца приложения) вместо выполнения произвольного кода)
Другое дело, что это может быть полезно на ранней стадии разработки, поэтому вы можете поймать проблемы с памятью, прежде чем перейти к производству.
Это то, что MS должна сказать об этом: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx
Одна вещь, о которой говорилось выше, заключается в следующем: "Функция malloc имеет недостаток в зависимости от времени выполнения. У нового оператора есть недостаток в том, что он зависит от компилятора и зависит от языка."
Кроме того, "HeapAlloc может быть проинструктирован об увеличении исключения, если невозможно выделить память"
Итак, если вы хотите, чтобы ваша программа работала с любым CRT или, возможно, без CRT, вы бы использовали HeapAlloc. Возможно, только люди, которые будут делать такие вещи, будут писателями вредоносных программ. Другое использование может быть, если вы пишете приложение с интенсивной памятью с конкретными шаблонами распределения/использования памяти, которые вы бы вместо написания своего собственного распределителя кучи вместо использования CRT.