Учебники

Паскаль — Управление памятью

Эта глава объясняет динамическое управление памятью в Pascal. Язык программирования Pascal предоставляет несколько функций для выделения памяти и управления.

Выделение памяти динамически

Во время программирования, если вы знаете размер массива, это легко, и вы можете определить его как массив. Например, чтобы сохранить имя любого человека, оно может содержать до 100 символов, чтобы вы могли определить что-то следующим образом:

var
name: array[1..100] of char;

Но теперь давайте рассмотрим ситуацию, когда у вас нет представления о длине текста, который нужно сохранить, например, вы хотите сохранить подробное описание по теме. Здесь нам нужно определить указатель на строку, не определяя, сколько памяти требуется.

Паскаль предоставляет новую процедуру для создания переменных указателя.

program exMemory;
var
name: array[1..100] of char;
description: ^string;

begin
   name:= 'Zara Ali';
   
   new(description);
      if not assigned(description) then
         writeln(' Error - unable to allocate required memory')
      else
         description^ := 'Zara ali a DPS student in class 10th';
   writeln('Name = ', name );
   writeln('Description: ', description^ );
end.

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

Name = Zara Ali
Description: Zara ali a DPS student in class 10th

Теперь, если вам нужно определить указатель с определенным количеством байтов, чтобы он мог ссылаться на него позже, вы должны использовать функцию getmem или процедуру getmem , которая имеет следующий синтаксис:

procedure Getmem(
   out p: pointer;
   Size: PtrUInt
);

function GetMem(
   size: PtrUInt
):pointer;

В предыдущем примере мы объявили указатель на строку. Строка имеет максимальное значение 255 байтов. Если вам действительно не нужно так много места или больше места в байтах, подпрограмма getmem позволяет указать это. Давайте перепишем предыдущий пример, используя getmem

Live Demo

program exMemory;
var
name: array[1..100] of char;
description: ^string;

begin
   name:= 'Zara Ali';
   
   description := getmem(200);
      if not assigned(description) then
         writeln(' Error - unable to allocate required memory')
      else
         description^ := 'Zara ali a DPS student in class 10th';
   writeln('Name = ', name );
   writeln('Description: ', description^ );
   
   freemem(description);
end.

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

Name = Zara Ali
Description: Zara ali a DPS student in class 10th

Таким образом, у вас есть полный контроль, и вы можете передавать любое значение размера при выделении памяти в отличие от массивов, где после определения размер не может быть изменен.

Изменение размера и освобождение памяти

Когда ваша программа выходит, операционная система автоматически освобождает всю память, выделенную вашей программой, но в качестве хорошей практики, когда вам больше не нужна память, вы должны освободить эту память.

Паскаль предоставляет процедуру dispose для освобождения динамически создаваемой переменной с использованием процедуры new. Если вы выделили память с помощью подпрограммы getmem , то вам нужно использовать freemem подпрограммы, чтобы освободить эту память. Подпрограммы freemem имеют следующий синтаксис —

procedure Freemem(
   p: pointer;
  Size: PtrUInt
);

function Freemem(
   p: pointer
):PtrUInt;

Кроме того, вы можете увеличить или уменьшить размер выделенного блока памяти, вызвав функцию ReAllocMem . Давайте еще раз проверим вышеуказанную программу и воспользуемся подпрограммами ReAllocMem и freemem . Ниже приводится синтаксис для ReAllocMem

function ReAllocMem(
   var p: pointer;
   Size: PtrUInt
):pointer;   

Ниже приведен пример использования подпрограмм ReAllocMem и freemem:

Live Demo

program exMemory;
var
name: array[1..100] of char;
description: ^string;
desp: string;

begin
   name:= 'Zara Ali';
   desp := 'Zara ali a DPS student.';
   
   description := getmem(30);
      if not assigned(description) then
         writeln('Error - unable to allocate required memory')
      else
         description^ := desp;

   (* Suppose you want to store bigger description *)
   description := reallocmem(description, 100);
   desp := desp + ' She is in class 10th.';
   description^:= desp; 
   
   writeln('Name = ', name );
   writeln('Description: ', description^ );
   
   freemem(description);
end.

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

Name = Zara Ali
Description: Zara ali a DPS student. She is in class 10th

Функции управления памятью

Паскаль предоставляет множество функций управления памятью, которые используются для реализации различных структур данных и реализации низкоуровневого программирования на Паскале. Многие из этих функций зависят от реализации. Free Pascal предоставляет следующие функции и процедуры для управления памятью —

function Addr (X: TAnytype): указатель;

Возвращает адрес переменной

Назначенная функция (P: указатель): Boolean;

Проверяет правильность указателя

функция CompareByte (const buf1; const buf2; len: SizeInt): SizeInt;

Сравнивает 2 буфера памяти байт на байт

функция CompareChar (const buf1; const buf2; len: SizeInt): SizeInt;

Сравнивает 2 буфера памяти байт на байт

функция CompareDWord (const buf1; const buf2; len: SizeInt): SizeInt;

Сравнивает 2 буфера памяти байт на байт

функция CompareWord (const buf1; const buf2; len: SizeInt): SizeInt;

Сравнивает 2 буфера памяти байт на байт

функция Cseg: Word;

Возвращает сегмент кода

процедура Dispose (P: указатель);

Освобождает динамически выделяемую память

процедура Dispose (P: TypedPointer; Des: TProcedure);

Освобождает динамически выделяемую память

функция Dseg: Word;

Возвращает сегмент данных

процедура FillByte (var x; count: SizeInt; значение: Byte);

Заполняет область памяти 8-битным шаблоном

процедура FillChar (var x; count: SizeInt; Значение: Byte | Boolean | Char);

Заполняет область памяти определенным символом

процедура FillDWord (var x; count: SizeInt; значение: DWord);

Заполняет область памяти 32-битным шаблоном

процедура FillQWord (var x; count: SizeInt; значение: QWord);

Заполняет область памяти 64-битным шаблоном

Заполняет область памяти 16-битным шаблоном

процедура Freemem (p: указатель; размер: PtrUInt);

Освобождает выделенную память

процедура Freemem (p: указатель);

Освобождает выделенную память

процедура Getmem (out p: указатель; размер: PtrUInt);

Выделяет новую память

процедура Getmem (out p: указатель);

Выделяет новую память

процедура GetMemoryManager (var MemMgr: TMemoryManager);

Возвращает текущий менеджер памяти

функция High (Arg: TypeOrVariable): TOrdinal;

Возвращает максимальный индекс открытого массива или перечисления

function IndexByte (const buf; len: SizeInt; b: Byte): SizeInt;

Находит значение в байтах в диапазоне памяти

function IndexChar (const buf; len: SizeInt; b: Char): SizeInt;

Находит значение размера символа в диапазоне памяти

function IndexDWord (const buf; len: SizeInt; b: DWord): SizeInt;

Находит значение размера DWord (32-разрядное) в диапазоне памяти

function IndexQWord (const buf; len: SizeInt; b: QWord): SizeInt;

Находит значение размера QWord в диапазоне памяти

Функция Indexword (const buf; len: SizeInt; b: Word): SizeInt;

Находит значение размера слова в диапазоне памяти

function IsMemoryManagerSet: Boolean;

Установлен ли менеджер памяти

функция Low (Arg: TypeOrVariable): TOrdinal;

Возвращает самый низкий индекс открытого массива или перечисления

процедура Move (постоянный источник; var dest; count: SizeInt);

Перемещает данные из одного места в памяти в другое

процедура MoveChar0 (const buf1; var buf2; len: SizeInt);

Перемещает данные до первого нулевого символа

процедура New (var P: Pointer);

Динамически распределять память для переменной

процедура New (вар P: указатель; минусы: TProcedure);

Динамически распределяет память для переменной

функция Ofs (var X): LongInt;

Возвращает смещение переменной

функция ptr (sel: LongInt; off: LongInt): farpointer;

Объединяет сегмент и смещение к указателю

функция ReAllocMem (var p: указатель; размер: PtrUInt): указатель;

Изменяет размер блока памяти в куче

функция Seg (var X): LongInt;

Возвращает сегмент

процедура SetMemoryManager (const MemMgr: TMemoryManager);

Устанавливает менеджер памяти

функция Sptr: указатель;

Возвращает текущий указатель стека

функция Sseg: Word;

Возвращает значение регистра сегмента стека