Навеяла удалённая уже тема) параметры VirtualAlloc - MEM_COMMIT и MEM_RESERVE должны(!?) идти вместе (см.пример) и почему? Пример 1 работает корректно на xp sp2, т.к. 2 флага скомбинированы, 2й - нет. 3й опять таки работает, т.к. память зарезервирована при самом первом размещении. /сначала думал, что MEM_COMMIT уже содержит в своей сути резервирование памяти, а то куда её, собственно, тогда выделять, если не резервируя, а по сути оказывается механизм другой./ короче грабли. Внятное объяснение приветствуется).
Вроде что-то подобное пишут выходит что во втором случае память резервируется implicitly и НЕ освобождается/дерезервируется explicitly. how come?
Вопрос снимается, просто мой старый win32.hlp ))) скрывает всю инфу, поставляемую МС - заглянул в мсдн. однако(!) Брехня выходит... [edited] А вообще тёмная история получается((
asmfan Не чего не понял. MEM_RESERVE - резервирует виртуальное адресное пространство. MEM_COMMIT - выделяет физическую. Если нужно просто зарезервировать себе кусок памяти в виртуальном адресном пространстве, не занимая физическую, то вызываем MEM_RESERVE, потом если понадобилась физическая MEM_COMMIT. Если нужна сразу физическая, то сразу MEM_COMMIT. MSDN: То есть по нормальному нужно писать только один флаг.
FreeManCPM однако по МСДН обязательно комбинировать и пример 2 доказывает что одним commit не обойтись.
На самом деле у страниц есть "Page State". И флаг который мы передаём VirtualAlloc, становиться флагом страницы памяти. Флаг один, и он определяет в каком состоянии сейчас находится страница. Существует три состояния: Free, Reserved, Committed. То есть страница может находиться только в одном из этих состояний, и ни как ни в двух или трёх, так как я уже сказал флаг у страницы один. Я сам встречал примеры где делается MEM_PESERVE | MEM_COMMIT, но IMHO особого смысла в этом нету. Хотя может в некоторых реализациях и вправду сразу нельзя MEM_COMMIT. Хотя опять же ясно сказано, что параметр должен быть одним значением, а не комбинацией.
Booster Суть - если пишем только MEM_COMMIT, то винда сама резервирует по определённому адресу память (противоречие с мсдн где делать так низя без резервирования), а затем при удалении/де-резервировании с MEM_RELEASE "резерированность" не снимается(!) (см. 2) MSDN VirtualAlloc В общем грабли ещё те.
asmfan Не знаю у меня MSDN 2005, и там ясно про это сказано: . Так же ясно сказано что состояние у страницы одно, и если делаешь MEM_COMMIT, то оно устанавливается в Committed, и никакого Reserved быть не может, так как состояние может быть только одним из трёх: Free, Reserved, Committed. А в Committed само собой разумеется виртуальные адреса зарезервированы, иначе быть и не может.
asmfan А что значит "нет" ? Первый раз при lpvAddress = Null память выделяется и освобождается нормально - и VirtualFree возвращает OK и VirtualQuery показывает состояние MEM_FREE. А вот при второй попытке выделить память по тому же адресу происходит облом - почему не понятно, но ведь винда и не гарантирует выделение памяти по заданному адресу. Обнули esi и будет выделяться нормально, причем по тому же адресу - значит "резервированность" снимается, хотя и как-то хитро