Распределение памяти на код Windows C - PullRequest
3 голосов
/ 28 октября 2008

Я хотел бы знать, какой метод рекомендуется при программировании на Windows C: с помощью malloc или функции Win32 HeapAlloc (возможно, VirtualAlloc?).

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

Ответы [ 7 ]

18 голосов
/ 28 октября 2008

Придерживайтесь malloc, если у вас нет веских причин использовать что-то другое. Он будет реализован ниже с точки зрения примитивов выделения памяти ОС, но нет никакого реального преимущества в том, чтобы самим переходить на этот уровень.

Я полагаю, что для нескольких вызовов API необходим блок памяти, выделенный из кучи Windows, но вы узнаете, когда встретите их.

Или, если вы хотите сделать что-то более продвинутое, например, использовать разделяемую память, или вам нужно напрямую управлять разрешениями на страницах памяти, вам нужно будет рассматривать вызовы API Windows, такие как VirtualAlloc.

4 голосов
/ 29 октября 2008

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

В противном случае проще и, конечно, более просто использовать malloc ().

VirtualAlloc имеет отличную функцию MEM_RESET, которая делает недействительными данные в блоке памяти, но сохраняет их выделенными. Это означает, что если он перенесен на диск, Windows не потрудится вернуться на страницу при следующем обращении к нему. Хорошо, если у вас есть много мегабайт данных, которые могут внезапно стать ненужными, но вскоре у вас будет что-то еще, чтобы заполнить буфер.

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

3 голосов
/ 28 октября 2008

Еще одна вещь: malloc () гарантированно будет переносимым (по крайней мере, для любой реализации ANSI-C) и более элегантным.

2 голосов
/ 28 октября 2008

В некоторых ситуациях, используя такие функции, как HeapAlloc, HeapFree сделает вашу жизнь проще. Одним из примеров может быть: большое приложение, в котором вам нужно выделить память в одном модуле (скажем, в library1.dll) и освободить эту память в главном модуле (скажем, program.exe). Это можно сделать безопасно, если вы используете функции HeapAlloc, HeapResize и HeapFree, но это невозможно сделать с помощью библиотеки времени выполнения C (например, malloc, free, resize).

НО: если у вас нет веских причин, вам следует придерживаться функций malloc / free / resize. Кроме того, если вам нужно изменить разрешения выделенной памяти (например, чтобы сделать, если исполняемый, и т. Д.), Вы должны использовать такие функции, как VirtualAlloc, VirtualFree.

1 голос
/ 28 октября 2008

Вы можете сделать обертку и оставить возможность изменить детали реализации. Вы даже можете сравнить оба варианта с вашим кодом, а затем решить.

0 голосов
/ 02 февраля 2009

С HeapAlloc вы можете иметь отдельные кучи для разных задач / подсистем. Это может упростить анализ дампа больших приложений.

С помощью malloc вы можете использовать только одну кучу, но вы получаете некоторые оптимизации размещения, которые авторы CRT могли реализовать поверх OS HeapAlloc.

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

0 голосов
/ 28 октября 2008

В отличие от Роба, я иду другим путем ... Так как я решил кодировать под WinAPI, я использую нативные функции вместо Си во время выполнения, которые в любом случае являются лишь тонкой оболочкой.

...