Неперемещаемая память
Замечание. Все приводимые в данном пункте примеры выделения блоков памяти приводят к созданию блоков неперемещаемой памяти. Функциями выделения памяти, рассматриваемые в примерах, возвращают указатели, содержащие виртуальный (логический, но не физический) адрес этого блока.
- Блок неперемещаемой памяти характеризуется тем, что как бы он не перемещался физически, его виртуальный адрес остается неизменным.
Отметим, что
Для выделения блоков неперемещаемой памяти в Win32 можно использовать как библиотечные функции C и операторы С++, так и функции Windows, предоставляемые для этих целей системой Win32.
Для примера рассмотрим способы выделения блока неперемещаемой памяти для хранения массива целых чисел размерностью 256 элементов:
#define N 256Определим в программе указатель на массив целых чиселследующим образом (указатель p - 32-разрядное число, которое неинициализировано):
int *p;Для выделения блоков неперемещаемой памяти и работы с ними рекомендуется использовать обычные библиотечные функции С, так как они просты и привычны.
Можно выделить блок памяти, на который будет указывать p, следующим образом:
p=(int *)malloc(N*sizeof(int)); // или p=(int *)сalloc(N,sizeof(int));При этом c помощью функции malloc выделяется блок памяти размером 1024 байта (1 КБ), который может хранить 256 32-разрядных целых. Указатель, равный NULL, показывает, что выделение памяти не было успешным.
Можно также выделить такой блок память, используя следующий вызов функции calloc. Два параметра функции calloc перемножаются и в результате получается 1024 байта. Кроме того, функция calloc производит обнуление блока памяти.
Доступ к i-тому элементу массива, хранящегося в блоке памяти, на который ссылается p, осуществляется при помощи операции []:
. . . p[i] . . .Если необходимо увеличить размер блока памяти (например, удвоить его), то можно вызвать функцию:
int N_new=N*2; p=(int *)realloc(p, N_new*sizeof(int));Указатель является параметром функции, и указатель (возможно, отличающийся по значению от первого, особенно, если блок увеличивается) является возвращаемым значением функции realloc. Этот пример показывает, что операционная система может перемещать блок в рамках виртуальной памяти.
После окончания работы с памятью необходимо вызвать функцию, освобождающую блок памяти:
free(p);Замечание.Только указанные четыре функции (malloc, calloc, realloc, free) определены в стандарте ANSI языка C. Часто производители компиляторов реализуют несколько большее количество функций, наиболее распространенной из которых является функция _msize, возвращающая размер выделенного блока.
Помимо библиотечных функций С для выделения блоков неперемещаемой памяти и работы с ними можно использовать и операторы языка C++.
Приведем пример их использования:
p=new int[N]; // выделение блока памяти и инициализация указателя if(p!=NULL) { . . . p[i] . . . // использование значений элементов массива delete []p; // освобождение блока памяти }Для выделения блоков неперемещаемой памяти и работы с ними можно использовать вызовы функций ядра Windows.Ниже приведена функция Windows для выделения блока неперемещаемой памяти для указателя на целые:
int *p; // объявление указателя . . . p=(int *)GlobalAlloc(GPTR, N*sizeof(int));· Функция GlobalAlloc имеет два параметра: набор флагов и размер выделяемого блока в байтах. Если первый параметр функции GlobalAlloc задать нулевым, то это аналогично использованию флага GMEM_FIXED (равен нулю). Такой вызов функции GlobalAlloc эквивалентен вызову функции malloc. Можно также использовать флаг GMEM_ZEROPOINT для обнуления всех байтов выделяемого блока памяти. Флаг GPTR включает в себя флаги GMEM_FIXED и GMEM_ZEROPOINT.
· Виртуальный адрес, который выдает функция GlobalAlloc в приведенном примере, может использоваться в программе для доступа к выделенной памяти. Значение NULL говорит о том, что имеющейся в распоряжении памяти для выделения недостаточно.
Для каждой функции (за исключением одной), начинающейся со слова Global, существует другая, начинающаяся со слова Local. Эти два набора в Win32 идентичны. Два различных слова сохранены для совместимости с предыдущими версиями Windows, где функции Global возвращали дальние указатели, а функции Local - ближние.
Доступ к i-тому элементу массива, хранящегося в блоке памяти, на который ссылается p, осуществляется при помощи операции []:
. . . p[i] . . .Имеется также функция изменения размера блока памяти:
int N_new=N*2; p=(int *)GlobalReAlloc(p, N_new*sizeof(int), GMEM_FIXED);Можно использовать флаг GMEM_ZEROPOINT для обнуления добавляющихся в блок памяти байтов, если блок расширяется.
Существует функция, возвращающая размер блока памяти и функция освобождения памяти:
DWORD dwSize=GlobalSize(p);и
GlobalFree(p);Дата добавления: 2017-01-26; просмотров: 1024;