Програмування для windows nt
Функції, призначені для роботи з віртуальною пам'яттю, які ми розглянули вище, зазвичай використовують для отримання в користування блоків пам'яті щодо великого розміру (більше однієї сторінки). Однак найбільш часто додатку потрібно всього кілька десятків байт, наприклад, для створення динамічних структур або для завантаження ресурсів програми в оперативну пам'ять. Очевидно, оперуючи з окремими сторінками, ви навряд чи зможете легко і ефективно працювати з блоками пам'яті невеликого обсягу.
Тому в програмному інтерфейсі Microsoft Windows NT були передбачені інші функції, до вивчення яких ми і переходимо. Всі ці функції викликають тільки що розглянуті нами функції, що працюють з віртуальною пам'яттю.
Пули пам'яті в Microsoft Windows NT
Як ми вже говорили, додатки Microsoft Windows версії 3.1 могли замовляти пам'ять з двох областей або двох пулів - з глобального пулу, доступного всім додаткам, і локального, створюваного для кожної програми.
В даному випадку для стандартного пулу буде зарезервовано 2 Мбайта пам'яті, причому відразу після завантаження програми 10 Кбайт пам'яті буде отримано в користування.
По-друге, параметри стандартного пулу можна вказати у файлі визначення модуля (який є необов'язковим). Наприклад, так:
Функції для роботи з пулами пам'яті
Отже, в розпорядженні додатки Microsoft Windows NT є один стандартний пул і довільну кількість динамічних пулів пам'яті.
В якості першого парметри всіх функцій, призначеним для отримання пам'яті з стандартного або динамічного пулу, необхідно передати ідентифікатор пулу.
Отримання ідентифікатора стандартного пулу
Ідентифікатор стандартного пулу отримати дуже просто. Цей ідентифікатор повертає функція GetProcessHeap XE "GetProcessHeap". не має параметрів:
Створення динамічного пулу
Якщо вам потрібен динамічний пул, ви можете його створити за допомогою функції HeapCreate XE "HeapCreate":
Параметри dwMaximumSize і dwInitialSize визначають, відповідно, розмір зарезервованої для пулу пам'яті і розмір пам'яті, отриманої для використання.
Через параметр flOptions ви можете передати нульове значення, а також значення HEAP_NO_SERIALIZE XE "HEAP_NO_SERIALIZE" і HEAP_GENERATE_EXCEPTIONS XE "HEAP_GENERATE_EXCEPTIONS".
Параметр HEAP_NO_SERIALIZE XE "HEAP_NO_SERIALIZE" має відношення до мультизадачности, яка буде розглянута в окремому розділі нашої книги. Якщо цей параметр не вказано, що працюють паралельно завдання одного процесу не можуть одночасно отримувати доступ до такого пулу. Ви можете використовувати прапор HEAP_NO_SERIALIZE для підвищення продуктивності, якщо створюваним вами пулом буде користуватися тільки одне завдання процесу.
При виділенні пам'яті з пулу можуть виникати помилкові ситуації. Якщо не вказано прапор HEAP_GENERATE_EXCEPTIONS XE "HEAP_GENERATE_EXCEPTIONS". при помилках соотвтетвующій функції повертатимуть значення NULL. В іншому випадку в додатку будуть генеруватися виключення. Прапор HEAP_GENERATE_EXCEPTIONS зручний в тих випадках, коли в вашому додатку передбачена обробка винятків, що дозволяє виправляти виникаючі помилки.
У разі успіху функція HeapCreate XE "HeapCreate" повертає ідентифікатор створеного динамічного пулу пам'яті. При помилковому повертає значення NULL (або виникає виняток, якщо вказано прапор HEAP_GENERATE_EXCEPTIONS).
Видалення динамічного пулу
Для видалення динамічного пулу пам'яті, створеного функцією HeapCreate XE "HeapCreate". ви повинні використовувати функцію HeapDestroy XE "HeapDestroy":
Через єдиний параметр цієї функції передається ідентифікатор видаляється динамічного пулу. Зауважимо, що вам не слід видаляти стандартний пул, передаючи цієї функції значення, отримане від функції GetProcessHeap XE "GetProcessHeap".
Функція HeapDestroy XE "HeapDestroy" виконує безумовне видалення пулу пам'яті, навіть якщо з нього були отримані блоки пам'яті і на момент видалення пулу вони не були повернуті системі.
Отримання блоку пам'яті з пулу
Для отримання пам'яті з стандартного або динамічного пулу додаток повинен скористатися функцією HeapAlloc XE "HeapAlloc". прототип якої ми привели нижче:
Що стосується параметра hHeap, то для нього ви можете використовувати або ідентифікатор Страндартное пулу пам'яті, отриманого від функції GetProcessHeap XE "GetProcessHeap". або ідентифікатор динамічного пулу, створеного додатком за допомогою функції HeapCreate XE "HeapCreate".
Параметр dwBytes визначає потрібний додатком обсяг пам'яті в байтах.
Параметр dwFlags може бути комбінацією наступних значень:
Виділена пам'ять заповнюється нулями
Зміна розміру блоку пам'яті
За допомогою функції HeapReAlloc XE "HeapReAlloc" додаток може змінити розмір блоку пам'яті, виділеного раніше функцією HeapAlloc XE "HeapAlloc". зменшивши або збільшивши його. Прототип функції HeapReAlloc наведено нижче:
Визначення розміру блоку пам'яті
У разі помилки ця функція повертає значення 0xFFFFFFFF.
Якщо блоком пам'яті користується тільки одна задача процесу, ви можете передати через параметр dwFlags значення HEAP_NO_SERIALIZE XE "HEAP_NO_SERIALIZE".
звільнення пам'яті
Пам'ять, виділену за допомогою функції HeapAlloc XE "HeapAlloc". слід звільнити, як тільки в ній відпаде потреба. Це потрібно зробити за допомогою функції HeapFree XE "HeapFree":
Якщо блоком пам'яті користується тільки одна задача процесу, ви можете передати через параметр dwFlags значення HEAP_NO_SERIALIZE XE "HEAP_NO_SERIALIZE".
Якщо розмір блоку пам'яті, виділеного функцією HeapAlloc XE "HeapAlloc". був змінений функцією HeapReAlloc XE "HeapReAlloc". для звільнення такого блоку пам'яті ви все одно повинні використовувати функцію HeapFree XE "HeapFree".
Використання функцій malloc XE "malloc" і free XE "free"
У бібліотеці Microsoft Visual C ++ є стандартні функції, призначені для динамічного отримання і звільнення пам'яті, такі як malloc XE "malloc" і free XE "free".
У нас є хороша новина для вас - в середовищі Microsoft Windows NT ви можете використовувати ці функції з тією ж ефективністю, що і функції, призначені для роботи з пулами - HeapAlloc XE "HeapAlloc". HeapFree XE "HeapFree" і так далі. Правда, ці функції отримують пам'ять тільки зі стандартного пулу.
Одна з переваг функцій malloc XE "malloc" і free XE "free" полягає в можливості їх використання на інших платформах, відмінних від Microsoft Windows NT.
Старі функції управління пам'яттю
У 32-розрядних додатках Microsoft Windows NT ви можете користуватися багатьма функціями управління пам'яттю операційної системи Microsoft Windows версії 3.1, які залишені в новій операційній системі для сумісності. Ми докладно розглянули ці функції в розділі "Управління пам'яттю" 13 томи "Бібліотеки системного програміста".
Нагадаємо, що в 16-розрядному програмному інтерфейсі Microsoft Windows версії 3.1 існує два набори функцій (глобальні та локальні), призначених для роботи з глобальним і локальним пулом пам'яті. Це такі функції, як GlobalAlloc XE "GlobalAlloc". LocalAlloc XE "LocalAlloc". GlobalFree XE "GlobalFree". LocalFree XE "LocalFree" і так далі. У 32-розрядних додатках Microsoft Windows NT ви можете користуватися як глобальними, так і локальними функціями, причому результат буде абсолютно однаковий. Причина цього полягає в тому, що всі ці функції користуються функціями програмного інтерфейсу Microsoft Windows NT, призначеними для роботи зі стандартним пулом пам'яті: HeapAlloc XE "HeapAlloc". HeapReAlloc XE "HeapReAlloc". HeapFree XE "HeapFree" і так далі.
Ось список функцій старого програмного інтерфейсу, доступних додатків Microsoft Windows NT:
Визначення ідентифікатора глобального (локального) блоку пам'яті
Звернемо вашу увагу також на те, що в середовищі Microsoft Windows версії 3.1 ви могли отримувати фіксовану (fixed), переміщувану (moveable) і видаляємо (discardable) пам'ять.
Що ж стосується видаляється пам'яті, то її можна використовувати для зберігання таких даних, які можна легко відновити, наприклад, прочитавши їх з ресурсів додатків.