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

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

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

Спасибо!

8 ответов

Решение

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

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

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

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

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

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

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

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

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

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

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

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

Ура & hth.,

В системах, где несколько библиотек DLL могут приходить и уходить (через LoadLibrary/Freelibrary), и когда память может быть выделена в одной библиотеке DLL, но освобождена в другой (см. Предыдущий ответ), HeapAlloc и связанные с ним функции кажутся наименее общим знаменателем для успешное разделение памяти.

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

Мы являемся встроенным магазином C++, поэтому мы перегружаем оператор new/delete по всей нашей системе, чтобы использовать HeapAlloc( GetProcessHeap()), который может иметь заглушку (на цели) или нативную (для окон) для переносимости кода.

До сих пор никаких проблем теперь, когда мы обошли таНос / бесплатно, которые, кажется, неоспоримо DLL в частности, новая "куча" для каждой загрузки DLL.

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

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.

malloc экспортируется функцией C-библиотеки времени выполнения (CRT), которая зависит от компилятора.
Имя библиотеки DLL времени выполнения C изменяется от версий Visual Studio до версий.

ФункцияHeapAlloc экспортируется с помощью kernel32.dll, присутствующего в папке Windows.

Другие вопросы по тегам