Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Использование кучи в Delphi.
Программируя в Delphi мы постоянно явно или неявно взаимодействуем с менеджером кучи. Неявно его используют все функции или конструкции языка, требующие выделения памяти: создания объекта класса, создание динамического массива или длинной строки. Явное взаимодействие с этим механизмом происходит при использовании следующих функций Delphi: New, Dispose, GetMem, AllocMem, ReallocMem, FreeMem. procedure New(var P: Pointer); Функция выделяет динамическую память в куче. Параметром принимает типизированный указатель, затем инициирует его адресом выделенного участка. Не имеет смысла использовать функцию с нетипизированным указателем, он просто останется со значением NIL. procedure Dispose(var P: Pointer); Функция освобождает память в куче. Параметром принимает типизированный указатель возвращенный функцией New(). Используется только в паре с функцией выделения памяти New(). function summ(var1, var2: integer): integer;var f_int: ^integer; s_int: ^integer; begin // выделим память new(f_int); new(s_int); f_int^:= var1; s_int^:= var2; Result:= f_int^ + s_int^; // освободим память dispose(f_int); dispose(s_int); end;Вышеприведенные функции используются для динамического выделения памяти с использованием типизированных указателей малого размера. Для работы с двоичными буферами и иными структурами данных большого размера используется следующий набор функций. procedure GetMem(var P: Pointer; Size: Integer); Выделяет блок памяти указанного размера. Можно использовать нетипизированный указатель. Если свободной памяти не окажется, то будет сгенирированно исключение EOutOfMemory. После выделения в памяти содержится всякий мусор. function AllocMem(Size: Cardinal): Pointer; Соответствует функции GetMem(), но после выделения память будет инициирована нулями. Возвращает указатель, как результат, а не как параметр, в отличие от той же GetMem(). procedure ReallocMem(var P: Pointer; Size: Integer); Деиствие зависит от значений P и Size. P может быть пустым указателем или содержать адрес участка памяти, возвращенный функциями GetMem, AllocMem и ReallocMem. ((P = NIL) and (Size <> 0)): выделяет новый блок памяти и устанавливает P на его адрес. Можно использовать вместо GetMem(); ((P <> NIL) and (Size = 0)): освобождает память, адресуемую P. P будет установлен в NIL. Похоже на FreeMem(), но в отличае от него чистит указатель. ((P <> 0) and (Size <> 0)): перевыделяет указанный блок памяти (изменяет его размер). Существующие данные затронуты не будут, но если память увеличиться, то новое пространство будет содержать всякий мусор. Если для изменения размера не будет хватать памяти, то блок может быть перенесен на другое место в пределах кучи, P будет указывать на новое место.
procedure FreeMem(var P: Pointer[; Size: Integer]); Функция освобождает память, выделенную в GetMem и AllocMem. Может принимать размер памяти, которую нужно освободить. Надо быть крайне осторожным с этим параметром, так как тут может появиться утечка. После освобождения памяти указатель P будет содержать мусор. Если в качестве параметра передана структура, содержащая длинные строки, варианты, динамические массивы или интерфейсы, тогда перед выполнением FreeMem будет вызвана Finalize. Небольшой пример: procedure useMemoryManager;type // шаблончик для доступа к памяти побайтово memcells = array[0..$7FFFFFFE] of byte; var p: pointer; i: integer; begin // выделим память GetMem(p, 100); // и инициируем ее какими-нибудь числами for i:=0 to 99 do memcells(p^)[i]:= byte(i); // добавим памяти ReallocMem(p, 200); // и допишим числа for i:=0 to 99 do memcells(p^)[i+100]:= byte(i+100); // … посмотрим, что получилось for i:=0 to 199 do writeln(inttostr(memcells(p^)[i])); // уберем после себя FreeMem(p);end;Работа с менеджером памяти Помимо выделения освобождения памяти существует возможность непосредственного взаимодействия с менеджером памяти в Delphi. Например мы можем получить информацию о текущем состоянии менеджера, о произошедших ошибках и даже назначить свои механизмы выделения и освобождения памяти. Во-первых есть несколько глобальных переменных, управляемых менеджером. var AllocMemCount: integer; Эта переменная содержит количество выделенных блоков памяти. Используется для определения оставшихся блоков. var AllocMemSize: integer; Содержит размер в байтах всех выделенных блоков. Сколько всего памяти из кучи выделенно программе. Эта переменная тоже глобальна, поэтому так же как и AllocMemCount следует использовать с осторожностью. var HeapAllocFlags: word; Набор флагов, устанавливающих опции для менеджера памяти. (по умолчанию – GMEM_MOVEABLE)
Во-вторых, существует ряд полезных функций для управления менеджером. function GetHeapStatus(): TheapStatus; Узнать текущее состояние диспетчера памяти. Если используется SharedMem, то статус относится к куче разделяемой несколькими процессами.
|
||||||||||||||||||||||
Последнее изменение этой страницы: 2017-02-21; просмотров: 501; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.129.70.157 (0.005 с.) |