
- •1.1 Основы программирования в операционной системе Windows
- •1.1.1 Вызов функций api
- •1.1.2 Структура программы
- •1.2 Вопросы системного программирования в Windows
- •1.2.1 Страничная и сегментная адресация.
- •1.2.2 Адресное пространство процесса.
- •2.1 Управление процессами
- •2.2 Процессы и потоки в Windows
- •2.3 Создание процессов
- •2.4 Определение исполняемого образа и командной строки
- •2.5 Идентификация процессов
- •3.1 Создание потока. Функция CreateThread
- •3.2. Завершение потока
- •3.3 Другие функции работы с потоками
- •3.4 Структура context
- •3.5 Приоритеты потоков
- •4.1 Объект critical_section
- •4.2 Мьютексы
- •4.3 Семафоры
- •5.1 События
- •7.1 Кучи
- •7.2 Управление памятью кучи
- •Другие функции для работы с кучей
- •Резюме по управлению кучей
- •Отображение адресного пространства процесса в объекты отображения
- •Что такое импорт
- •Явная загрузка dll
- •Явное подключение экспортируемого идентификатора
- •10.1 Управление файлами и каталогами Создание и открытие файлов
- •10.2 Управление каталогами
- •10.3 Другие методы получения атрибутов файлов и каталогов
- •11.1 Блокировка файлов
- •11.2 Реестр
- •12.1 Стандартные устройства и консольный ввод-вывод
- •12.2 Асинхронный ввод-вывод и порты завершения
- •Параметры
- •Цели системы безопасности
- •Параметры
- •Аварийное завершение
- •Использование именованных каналов
- •Параметры
- •Наблюдение за сообщениями в именованном канале
- •Параметры
7.2 Управление памятью кучи
Выделение блоков памяти из кучи осуществляется путем указания дескриптора кучи, размера блока и нескольких флагов.
LPVOID HeapAlloc ( HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
Возвращаемое значение: указатель на выделенный блок памяти или NULL при неудаче (кроме случаев,- когда задано генерирование исключений).
Параметры функции HeapAlloc
hHeap — дескриптор кучи, из которой должен быть выделен блок памяти. Этот дескриптор должен быть получен функциями GetProcessHeap или HeapCreate.
dwFlags представляет собой комбинацию трех флагов.
• HEAP_GENERATE_EXCEPTIONS И HEAP_NO_SERIALIZE имеют то же значение, что и для функции HeapCreate. Первый флаг можно не указывать, если он был установлен функцией HeapCreate для данной кучи. Второй флаг используется при выделении памяти из кучи процесса.
• HEAP_ZERO_MEMORY указывает на то, что выделенная память будет заполнена нулями; в противном случае содержимое памяти будет неопределенным.
dwBytes — размер блока памяти, который должен быть выделен. Для невозрастающих куч его предел составляет 0x7FFF8 (примерно 0,5 Мбайт).
Освобождение памяти из кучи выполняется элементарно.
BOOL HeapFree ( HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
dwFlags должен быть равен нулю или константе HEAP_NO_SERIALIZE.
lpMem должен иметь значение, возвращенное функцией HeapAlloc или HeapReAlloc,
а hHeap — это, конечно, дескриптор кучи, из которой был выделен блок lpMem.
Для изменения размера блоки памяти могут быть выделены заново.
LPVOID HeapReAlloc ( HANDLE hHeap, DWORD dwFlags,
LPVOID lpMem, SIZE_T dwBytes)
Возвращаемое значение: указатель на выделенный заново блок. При неудаче возвращает NULL или вызывает исключение.
Параметры функции HeapReAlloc
Первый параметр hHeap упоминался выше. dwFlags указывает некоторые важные управляющие флаги.
• HEAP_GENERATE_EXCEPTIONS и HEAP_NO_SERIAL_S1ZE, как в предыдущих случаях.
• HEAP_ZERO_MEMORY — инициализируется только заново выделяемая память (когда значение dwByte больше размера исходного блока). Содержимое исходного блока не изменяется.
• HEAP_REALLOC_IN_PLACE_ONLY указывает на то, что блок не может быть перемешен. При увеличении размера блока память должна выделяться по адресу, следующему сразу после существующего блока.
lpMem указывает на существующий блок в куче hHeap, который должен быть выделен заново.
dwBytes — новый размер блока, который может быть больше или меньше текущего.
Обычно возвращаемый указатель — тот же, что и значение lpMem. Если же блок был перемещен (это разрешается, когда флаг HEAP_REALLOC_IN_PLACE_ONLY опущен), то возвращенное значение будет другим. Следите за обновлением всех ссылок на блок.
Размер выделенного блока определяется функцией НеарSize (на самом деле имя этой функции должно быть BlockSize, так как она относится к блоку, а не к куче) с указанием дескриптора кучи и указателя на блок.
DWORD HeapSize ( HANDLE hHeap, DWORD dwFlags,
LPCVOID lpMem)
Возвращаемое значение:.размер блока или нуль при неудаче.
Флаг HEAP_NO_SER IALIZE
В функциях HeapCreate, HeapAlloc и HeapReAlloc может быть указан флаг HEAP_NO_SERIALIZE. Его применение позволяет получить небольшой прирост быстродействия, производительности, так как функции не предоставляют потокам взаимные исключения при доступе к куче. Применение этого флага безопасно в немногих описанных ниже ситуациях.
• Программа не использует потоки, или, точнее, процесс имеет только один поток.
• Каждый поток имеет собственную кучу или группу куч, к которым не обращаются другие потоки.
• Программа имеет собственный механизм взаимных исключений для предотвращения одновременного доступа к куче нескольких потоков, использующих функции HeapAlloc и HeapReAlloc. Для тех же целей в Windows 2000/NT доступны функции HeapLock и HeapUnlock.
Флаг HEAP_GENERATE__EXCEPTIONS
Вызов исключений в случае неудачного выделения памяти делает ненужными раздражающие проверки ошибок после каждого выделения. Более того, исключение или обработчик завершения может очистить память, которая была выделена. Возможны два кода исключения.
1. STATUS_NO_MEMORY указывает на то, что система не может создать блок заданного размера. Причиной может быть фрагментация памяти, невозрастающая куча, которая достигла своего предела, или даже исчерпание всей памяти возрастающими кучами.
2. STATUS_ACCESS_VIOLATION указывает на то, что куча была повреждена. Например, программа могла произвести запись в память за границами выделенного блока.