Windows для профессионалов


Сброс содержимого физической памяти - часть 2


Но, хотя ее содержимое не обнуляется, читать такую страницу памяти уже пельзя Если системе не понадобится эта страница оператикной памяти, ее содержимое останется прежним. В ином слу чае система может забрать ее в свое распоряжение, и тогда обращение к этой стра нице приведет к тому, что система предоставит программе новую страницу, заполнен ную нулями. А поскольку этот процесс нам не подвластен, лучше считать, что после сброса страница содержит только мусор

При сбросе физической памяти надо учитывать и несколько других моментов. Во первых, когда Вы вызываете VtrtualAlloc, базовый адрес обычно округляется до бли жайшего меньшего значения, кратного размеру страниц, а количество байтов — до ближайшего большего значения, кратного той же величине. Такой механизм округ ления базового адреса и количества байтов был бы очень опасен при сбросе физи ческой памяти; поэтому VirtualAlloc при передаче ей флага MEMRESET округляет эти значения прямо наоборот.Допустим, в Вашей программе есть следующий исходный код:

PINT pnData = (PINT) VirtualAlloc(NULL, 1024, MEM_FlESERVE | MEM_COMMIT, PAGE_READWRITE);

pn[0] = 100;
pn[1] = 200;

VirtualAlloc((PVOID) pnData, sizeof(int), MEM_RESFT, PAGE_READWRITE);

Этот код передает одну страницу памяти, а затем сообщает, что первые четыре байта (sizeof(int)) больше не нужны и их можно сбросить. Однако, как и при любых других действиях с памятью, этa операция выполняется только над блоками памяти, размер которых кратен размеру страниц В данном случае вызов завершится неудач но (VirtualAlloc вернет NULL) Почему? Дело в том, что при вызове VirtualAlloc Вы ука зали флаг MEM_RESET и базовый адрес, переданный функции, теперь округляется до ближайшего большего значения, кратного размеру страниц, а количество байтов — до ближайшего меньшего значения, кратного той же величине Так делается, чтобы исключить случайную потерю важных данных В предыдущем примере округление количества байтов до ближайшего меньшего значения дает 0, а эта величина недо пустима.

Второе, о чем следует помнить при сбросе памяти, — флаг MEM_RESET нельзя комбинировать (логической операцией OR) ни с какими другими флагами. Следую щий вызов всегда будет заканчиваться неудачно:

PVOID pvMem = VirtualAlloc(NULL, 1024, MEM_RESERVE | MEM_COMMIT | MFM_RESET, PAGE_READWRITE);

Впрочем, комбинировать флаг MEM_RESET с другими флагами все равно бессмысленно

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




Начало  Назад  Вперед



Книжный магазин