Исходный текст приложения
Исходный текст приложения HEAPMEM представлен в листинге 1.5. Файлы описания ресурсов и определения модуля не используются.
Листинг 1.5. Файл heapmem/heapmem.c
#include <windows.h>
#include <stdio.h>
#include <conio.h>
int main()
{
// Идентификатор динамического пула
HANDLE hHeap;
// Указатель, в который будет записан адрес
// полученного блока памяти
char *lpszBuff;
// =================================================
// Работа с динамическим пулом
// Используем структурную обработку исключений
// =================================================
// Создаем динамический пул
hHeap = HeapCreate(0, 0x1000, 0x2000);
// Если произошла ошибка, выводим ее код и
// завершаем работу приложения
if(hHeap == NULL)
{
fprintf(stdout,"HeapCreate: Error %ld\n",
GetLastError());
getch();
return 0;
}
// Пытаемся получить из пула блок памяти
__try
{
lpszBuff = (char*)HeapAlloc(hHeap,
HEAP_GENERATE_EXCEPTIONS, 0x1500);
}
// Если память недоступна, происходит исключение,
// которое мы обрабатываем
__except (EXCEPTION_EXECUTE_HANDLER)
{
fprintf(stdout,"1. HeapAlloc: Exception %lX\n",
GetExceptionCode());
}
// Пытаемся записать в буфер текстовую строку
__try
{
strcpy(lpszBuff, "Строка для проверки");
}
// Если содержимое указателя lpszBuff равно NULL,
// произойдет исключение
__except (EXCEPTION_EXECUTE_HANDLER)
{
fprintf(stdout,"1. strcpy: Exception %lX \n",
GetExceptionCode());
}
// Выполняем повторную попытку, указывая меньший
// размер блока памяти
__try
{
lpszBuff = (char*)HeapAlloc(hHeap,
HEAP_GENERATE_EXCEPTIONS, 0x100);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
fprintf(stdout,"2. HeapAlloc: Exception %lX\n",
GetExceptionCode());
}
__try
{
strcpy(lpszBuff, "Test string");
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
fprintf(stdout,"2. strcpy: Exception %lX \n",
GetExceptionCode());
}
// Отображаем записанную строку
if(lpszBuff != NULL)
printf("String:>%s<\n", lpszBuff);
// Изменяем размер блока памяти
__try
{
HeapReAlloc(hHeap, HEAP_GENERATE_EXCEPTIONS |
HEAP_REALLOC_IN_PLACE_ONLY, lpszBuff, 150);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
fprintf(stdout,"HeapReAlloc: Exception %lX \n",
GetExceptionCode());
}
// Освобождаем блок памяти
if(lpszBuff != NULL)
HeapFree(hHeap, HEAP_NO_SERIALIZE, lpszBuff);
// Удаляем пул памяти
if(!HeapDestroy(hHeap))
fprintf(stdout,"Ошибка %ld при удалении пула\n",
GetLastError());
// =================================================
// Работа со стандартным пулом
// Исключения не обрабатываем
// =================================================
// Получаем блок памяти из стандартного пула
lpszBuff = (char*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, 0x1000);
// Если памяти нет, выводим сообщение об ошибке
// и завершаем работу программы
if(lpszBuff == NULL)
{
fprintf(stdout,"3. HeapAlloc: Error %ld\n",
GetLastError());
getch();
return 0;
}
// Выполняем копирование строки
strcpy(lpszBuff, "Test string");
// Отображаем скопированную строку
printf("String:>%s<\n", lpszBuff);
// Освобождаем блок памяти
if(lpszBuff != NULL)
HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, lpszBuff);
// =================================================
// Работа со стандартными функциями
// Исключения не обрабатываем
// =================================================
lpszBuff = malloc(1000);
if(lpszBuff != NULL)
{
strcpy(lpszBuff, "Test string");
printf("String:>%s<\n", lpszBuff);
free(lpszBuff);
}
printf("Press any key...");
getch();
return 0;
}
В отличие от обычного приложения Microsoft Windows NT, исходный текст консольного приложения должен содержать функцию main (аналогично программе MS-DOS). В теле этой функции мы определили переменные hHeap и lpszBuff. Первая из них используется для хранения идентификатора динамического пула памяти, вторая - для хранения указателя на полученный блок памяти.