Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Выбор правильного метода выделения
Используйте следующее руководство, чтобы выбрать соответствующий API выделения памяти для вашего сценария:
| Scenario | Рекомендуемый API | Примечания |
|---|---|---|
| Выделения C++ общего назначения | new / std::make_unique / std::make_shared |
Выбор кода C++ по умолчанию. Внутренне использует кучу CRT. RAII обеспечивает автоматическую очистку. |
| Выделение C общего назначения | malloc / calloc / realloc |
Выбор по умолчанию для кода C. Переносимые на разных платформах. |
| Выделение больше 1 МБ или требует элемента управления на уровне страницы | VirtualAlloc | Выделяется при детализации страниц (обычно 4 КБ). Используется для резервирования больших диапазонов адресов, страниц охранников или памяти с определенными атрибутами защиты (PAGE_READWRITE, PAGE_EXECUTE_READи т. д.). |
| Многие небольшие выделения с пользовательским элементом управления (например, распределитель пула) | КучиAlloc / HeapCreate | Создайте частную кучу для элемента управления изоляцией или сериализации. Используйте HEAP_NO_SERIALIZE только в том случае, если куча является исключительно однопоточной. |
| COM-взаимодействие (маршалированная память) | CoTaskMemAlloc | Требуется, когда память пересекает границы com-квартиры. Заглушки, созданные MIDL, используют CoTaskMemAlloc/CoTaskMemFree. |
| Устаревший код с помощью перемещаемой памяти | GlobalAlloc / LocalAlloc | Избегайте нового кода. Они добавляют дополнительные затраты на HeapAlloc и существуют в первую очередь для обратной совместимости с операциями буфера обмена и определенными API Win32, которые требуют их. |
Important
Всегда правильно распределить пары и функции распределения сделки. Выделенная память должна HeapAlloc быть освобождена с помощью HeapFree —нет free() или LocalFree. Сочетание семей распределения и распределения сделки приводит к повреждению кучи, которая трудно диагностировать.
Note
VirtualAlloc vs HeapAlloc: VirtualAlloc работает с степенью детализации страницы (минимум 4 КБ, резервирования, выровненные по SYSTEM_INFO.dwAllocationGranularityсравнению с 64 КБ). Выделение большого количества небольших объектов с адресным пространством виртуальныхalloc. Используйте HeapAlloc (или malloc/new) для небольших частых выделений. Используйте VirtualAlloc, если необходимо зарезервировать большие области адресов, защиту страниц управления или реализовать пользовательские распределители.
Подробное сравнение
Ниже приведено краткое сравнение различных методов выделения памяти:
- CoTaskMemAlloc
- GlobalAlloc
- КучиAlloc
- LocalAlloc
- Malloc
- Новое
- VirtualAlloc
Хотя функции GlobalAlloc, LocalAlloc и HeapAlloc в конечном итоге выделяют память из одной кучы, каждая из них предоставляет немного другой набор функций. Например, HeapAlloc можно указать, чтобы вызвать исключение, если не удалось выделить память, возможность недоступна в LocalAlloc. LocalAlloc поддерживает выделение дескрипторов, которые позволяют перемещению базовой памяти путем перемещений без изменения значения дескриптора, возможности, недоступные в HeapAlloc.
Начиная с 32-разрядной Windows, GlobalAlloc и LocalAlloc реализуются как функции-оболочки, которые вызывают HeapAlloc с помощью дескриптора кучи по умолчанию процесса. Таким образом, GlobalAlloc и LocalAlloc имеют больше накладных расходов, чем HeapAlloc.
Так как различные кучи распределители предоставляют отличительные функциональные возможности с помощью различных механизмов, необходимо освободить память с правильной функцией. Например, память, выделенная с помощью HeapAlloc , должна быть освобождена с помощью HeapFree , а не LocalFree или GlobalFree. Память, выделенная с помощью GlobalAlloc или LocalAlloc , должна запрашиваться, проверяться и выпускаться с соответствующей глобальной или локальной функцией.
Функция VirtualAlloc позволяет указать дополнительные параметры выделения памяти. Однако его выделение использует детализацию страницы, поэтому использование VirtualAlloc может привести к более высокому использованию памяти.
Функция malloc имеет недостаток зависимости от времени выполнения. Новый оператор имеет недостаток зависимости компилятора и зависимого языка.
Функция CoTaskMemAlloc имеет преимущество эффективной работы в C, C++или Visual Basic. Это также единственный способ совместного использования памяти в приложении на основе COM, так как MIDL использует CoTaskMemAlloc и CoTaskMemFree для маршалирования памяти.
Примеры
Связанные темы