Распределение памяти на код Windows C
Я хотел бы знать, какой метод рекомендуется при программировании на Windows C: используя malloc или функцию Win32 HeapAlloc (может быть VirtualAlloc?).
Я прочитал статью о функциях управления памятью MSDN и статьи MSDN, касающиеся malloc и HeapAlloc, но в них не сказано, какой из них следует использовать и в каких ситуациях.
7 ответов
Придерживайтесь malloc, если у вас нет веских причин использовать что-то другое. Он будет реализован ниже с точки зрения примитивов выделения памяти ОС, но нет никакого реального преимущества в том, чтобы погружаться в этот уровень самостоятельно.
Я полагаю, что для нескольких вызовов API необходим блок памяти, выделенный из кучи Windows, но вы узнаете об этом.
Или, если вы хотите сделать что-то более продвинутое, например, использовать разделяемую память, или вам нужно напрямую управлять разрешениями на страницах памяти, вам нужно будет смотреть на вызовы API Windows, такие как VirtualAlloc.
VirtualAlloc и друзья могут дать вам преимущество, если у вас действительно есть куча данных для обработки или если вам все равно нужно заняться созданием собственного менеджера памяти.
В противном случае проще и, конечно, более просто использовать malloc ().
VirtualAlloc имеет эту замечательную функцию, которая называется MEM_RESET, которая делает недействительными данные в блоке памяти, но сохраняет их выделенными. Это означает, что если он перенесен на диск, Windows не потрудится вернуться на страницу при следующем обращении к нему. Хорошо, если у вас есть много мегабайт данных, которые могут внезапно стать ненужными, но вскоре у вас будет что-то еще, чтобы заполнить буфер.
Он также различает резервирование адресного пространства и фактический запрос памяти. Там есть кое-что приятное, если у вас есть веская причина, чтобы пойти на все эти неприятности.
Еще одна вещь: malloc() гарантированно будет переносимым (по крайней мере, для любой реализации ANSI-C) и более элегантным.
В некоторых ситуациях, используя такие функции, как HeapAlloc, HeapFree сделает вашу жизнь проще. Один из примеров: большое приложение, в котором вам нужно выделить память в одном модуле (скажем, в library1.dll) и освободить эту память в главном модуле (скажем, program.exe). Это можно сделать безопасно, если вы используете функции HeapAlloc, HeapResize и HeapFree, но это невозможно сделать с помощью библиотеки времени выполнения C (например, malloc, free, resize).
НО: если у вас нет веских причин, вам следует придерживаться функций malloc/free/resize. Кроме того, если вам нужно изменить разрешения выделенной памяти (например, чтобы сделать, если исполняемый, и т. Д.), Вы должны использовать такие функции, как VirtualAlloc, VirtualFree.
Вы можете сделать обертку и оставить возможность изменить детали реализации. Вы можете даже сравнить оба варианта с вашим кодом, а затем решить.
С HeapAlloc вы можете иметь отдельные кучи для разных задач / подсистем. Это может упростить анализ дампа больших приложений.
С помощью malloc вы можете использовать только одну кучу, но вы получаете некоторые оптимизации размещения, которые авторы CRT, возможно, реализовали поверх OS HeapAlloc.
Переход к VirtualAlloc не принесет вам больших выгод, если вы не захотите реализовать собственный менеджер кучи (свой собственный набор функций Heap*).
В отличие от Роба, я иду другим путем... Так как я решил кодировать в WinAPI, я использую нативные функции вместо Си во время выполнения, которые в любом случае являются лишь тонкой оболочкой.