На главную

On-line справка по Win32 API

Написать письмо
БЕСПЛАТНАЯ ежедневная online лотерея! Выигрывай каждый день БЕСПЛАТНО!
Список всех статей A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-V-W-X-Y-Z | Скачать Вниз

Using the Virtual Memory Functions



This section explains how to use the virtual memory functions for dynamic allocation.

The following example illustrates the use of the VirtualAlloc and VirtualFree functions in reserving and committing memory as needed for a dynamic array. First, VirtualAlloc is called to reserve a block of pages with NULL specified as the base address parameter, forcing the kernel to determine the location of the block. Later, VirtualAlloc is called whenever it is necessary to commit a page from this reserved region, and the base address of the next page to be committed is specified.

The example uses try-except structured exception-handling syntax to commit pages from the reserved region. Whenever a page fault exception occurs during the execution of the try block, the filter function in the expression preceding the except block is executed. If the filter function can allocate another page, execution continues in the try block at the point where the exception occurred. Otherwise, the exception handler in the except block is executed. For more information about structured exception handling, see Structured Exception Handling.

As an alternative to dynamic allocation, the process can simply commit the entire region instead of only reserving it. However, committing the region consumes physical storage that might not be needed, making it unavailable for use by other processes.
The example uses VirtualFree to free the reserved and committed pages when it is finished with them. The function is called twice: first to decommit the committed pages and again to release the entire region of reserved pages.

#define PAGELIMIT 80
#define PAGESIZE 0x1000

INT PageFaultExceptionFilter(DWORD);
VOID MyErrorExit(LPTSTR);

LPTSTR lpNxtPage;
DWORD dwPages = 0;

VOID UseDynamicVirtualAlloc(VOID) {
LPVOID lpvBase;
LPTSTR lpPtr;
BOOL bSuccess;
DWORD i;

/* Reserve pages in the process's virtual address space. */

lpvBase = VirtualAlloc(
NULL, /* system selects address */
PAGELIMIT*PAGESIZE, /* size of allocation */

MEM_RESERVE, /* allocates reserved pages */
PAGE_NOACCESS); /* protection = no access */
if (lpvBase == NULL )
MyErrorExit("VirtualAlloc reserve");

lpPtr = lpNxtPage = (LPTSTR) lpvBase;

/*
* Use try-except structured exception handling when
* accessing the pages. If a page fault occurs, the
* exception filter is executed to commit another page
* from the reserved block of pages.
*/

for (i=0; i < PAGELIMIT*PAGESIZE; i++) {


try {

/* Write to memory. */

lpPtr[i] = 'a';
}

/*
* If there is a page fault, commit another page
* and try again.
*/

except ( PageFaultExceptionFilter(
GetExceptionCode() ) ) {

/*
* This is executed only if the filter function is
* unsuccessful in committing the next page.
*/

ExitProcess( GetLastError() );


}

}

/* Release the block of pages when you are finished using them. */

/* First, decommit the committed pages. */

bSuccess = VirtualFree(
lpvBase, /* base address of block */
dwPages*PAGESIZE, /* bytes of committed pages */
MEM_DECOMMIT); /* decommit the pages */

/* Release the entire block. */

if (bSuccess)
bSuccess = VirtualFree(
lpvBase, /* base address of block */

0, /* releases the entire block */
MEM_RELEASE); /* releases the pages */

}

INT PageFaultExceptionFilter(DWORD dwCode) {
LPVOID lpvResult;

/* If the exception is not a page fault, exit. */

if (dwCode != EXCEPTION_ACCESS_VIOLATION) {
printf("exception code = %d\n", dwCode);
return EXCEPTION_EXECUTE_HANDLER;
}

printf("page fault\n");

/* If the reserved pages are used up, exit. */


if (dwPages >= PAGELIMIT) {
printf("out of pages\n");
return EXCEPTION_EXECUTE_HANDLER;
}

/* Otherwise, commit another page. */

lpvResult = VirtualAlloc(
(LPVOID) lpNxtPage, /* next page to commit */
PAGESIZE, /* page size, in bytes */
MEM_COMMIT, /* alloc committed page */
PAGE_READWRITE); /* read-write access */
if (lpvResult == NULL ) {
printf("VirtualAlloc failed\n");

return EXCEPTION_EXECUTE_HANDLER;
}

/*
* Increment the page count, and advance lpNxtPage
* to the next page.
*/

dwPages++;
lpNxtPage += PAGESIZE;

/* Continue execution where the page fault occurred. */

return EXCEPTION_CONTINUE_EXECUTION;

}



Пригласи друзей и счет твоего мобильника всегда будет положительным!
Предыдущая статья
 
Сайт Народ.Ру Интернет
Следующая статья
Пригласи друзей и счет твоего мобильника всегда будет положительным!

Использование Виртуальных Функций Памяти



Эта секция объясняет как, чтобы использовать виртуальные функции памяти для динамического распределения.

Следующий пример иллюстрирует использование VirtualAlloc и функций VirtualFree в резервном и совершать памяти как и требуется для динамического массива. Сначала, VirtualAlloc назван, чтобы резервировать блока страниц с НЕДЕЙСТВИТЕЛЬНЫМ определенным как базовый параметр адреса, заставляющий зерно, чтобы определять позицию блока. Позже, VirtualAlloc назван всякий раз, когда необходимо должно совершить страницу из этого зарезервировавшее регион, и базовый адрес следующей страницы, которые нужно совершать, определены.

Пример использует попытку-кроме исключительной обработки структурного синтаксиса, чтобы совершать страницы из резервного региона. Всякий раз, когда страничное дефектное исключение происходит в течение выполнения пробовать блока, функция фильтра в выражении, предшествующем за исключением того блок выполнен. Если функция фильтра может распределить другую страницу, выполнение остается в пробовать блока на данном этапе где исключение происходило. В противном случае, исключительный вручитель в за исключением того блок выполнен. Более подробно о структурном исключении, обрабатывающем, смотри Структурную Исключительную Обработку.

Как альтернатива для динамического распределения, процесс может просто совершить целый регион вместо только резервировать это. Тем не менее, совершающий регион поглощает физическое хранение, которое не могло быть нужно, делая это недоступно для использования другими процессами.
Пример использует VirtualFree, чтобы освобождать резервную и совершенную страницы когда она завершена ими. Функция называется дважды: сначала, чтобы decommit совершенные страницы и снова, чтобы выпускать целый регион резервных страниц.

#define PAGELIMIT 80 0x1000 #define PAGESIZE

INT PageFaultExceptionFilter(DWORD);
АННУЛИРУЙТЕ MyErrorExit(LPTSTR);

lpNxtPage LPTSTR;
DWORD dwPages = 0;

ПУСТОТА UseDynamicVirtualAlloc(ПУСТОТА) { LPVOID lpvBase;
LPTSTR lpPtr;
BOOL bSuccess;
i DWORD;

/* Зарезервируйте страницы в виртуальном адресе процесса space. */

lpvBase = VirtualAlloc(
НЕДЕЙСТВИТЕЛЬНЫЙ, /* система выбирается адрес */ PAGELIMIT*PAGESIZE, /* размер распределения */

MEM_RESERVE, /* распределяет резервные страницы */ PAGE_NOACCESS); /* защита = никакой доступ */ если (lpvBase == НЕДЕЙСТВИТЕЛЬНЫЙ ) MyErrorExit(резерв "VirtualAlloc");

lpPtr = lpNxtPage = (LPTSTR), lpvBase;

/*
* Попытка-Использование кроме структурной исключительной обработки когда
* получая страницы. Если страничный дефект происходит, .Jчемjтем
* исключительный фильтр выполнен, чтобы совершать другую страницу
* из резервного блока страниц.
*/

для (i=0; я < PAGELIMIT*PAGESIZE; я++) {


попытка {

/* Запись в memory. */

lpPtr[i] = 'a;
}

/*
* Если есть страничный дефект, совершите другую страницу
* и попытка снова.
*/

кроме ( PageFaultExceptionFilter( GetExceptionCode() ) ) {

/*
* Это выполняется только если функция фильтра
* неудачный на совершающей следующей странице.
*/

ExitProcess( GetLastError() );


}

}

/* Выпустите блока страниц когда Вы завершены используя them. */

/* Сначала, decommit совершенный pages. */

bSuccess = VirtualFree(
lpvBase, /* Базовый адрес блока */ dwPages*PAGESIZE, /* байты совершенных страниц */ MEM_DECOMMIT); /* decommit страницы */

/* Выпустите целый block. */

если (bSuccess) bSuccess = VirtualFree( lpvBase, /* базовый адрес блока */

0, /* выпускает целого блока */ MEM_RELEASE); /* выпускает страницы */

}

INT PageFaultExceptionFilter(DWORD dwCode) { LPVOID lpvResult;

/* Если исключение - не страничный дефект, exit. */

если (dwCode!= EXCEPTION_ACCESS_VIOLATION) { printf("exception кодировать = %d\n", dwCode);
возвращайте EXCEPTION_EXECUTE_HANDLER;
}

printf("page fault\n");

/* Если резервные страницы израсходованы, exit. */


если (dwPages >= PAGELIMIT) { printf("out pages\n");
возвращайте EXCEPTION_EXECUTE_HANDLER;
}

/* В противном случае, совершите другой page. */

lpvResult = VirtualAlloc lpNxtPage( (LPVOID), /* Следующая страница, чтобы совершаться */ PAGESIZE, /* страничный размер, в байтах */ MEM_COMMIT, /* распределите совершенную страницу */ PAGE_READWRITE); /* прочитайте-доступ записи */ если (lpvResult == НЕДЕЙСТВИТЕЛЬНЫЙ ) { printf("VirtualAlloc failed\n");

возвращайте EXCEPTION_EXECUTE_HANDLER;
}

/*
* Увеличьте страничный счет и предоставляйте lpNxtPage
* на следующую страницу.
*/

dwPages++;
lpNxtPage += PAGESIZE;

/* Продолжите выполнение где страничный дефект occurred. */

возвращайте EXCEPTION_CONTINUE_EXECUTION;

}



Вверх Version 1.3, Oct 26 2010 © 2007, 2010, mrhx Вверх
 mrhx software  Русский перевод OpenGL  Русский перевод Win32 API
 
Используются технологии uCoz