ReallocMem, процедура

Синтаксис


procedure ReallocMem(var P : Pointer; NewSize: Integer);

Описание

Процедура ReallocMem изменяет размер динамически выделенного блока памяти, максимально сохраняя его предыдущее содержимое.
Если Р равно nil, ReallocMem работает аналогично GetMem. Если NewSize равно нулю - аналогично FreeMem, т. е. значение Р не изменяется и после завершения процедуры содержит некорректное значение.
По мере возможности ReallocMem пытается изменить размер текущего блока памяти, но если это невозможно, выделяется новый блок требуемого размера и старые данные копируются в новый блок памяти. В любом случае, если NewSize больше текущего размера, дополнительная память не инициализируется.
ReallocMem не является настоящей процедурой.

Ошибки

Советы и приемы

  • Необходимо прогнозировать рост блока, увеличивающегося постепенно. Выгоднее увеличивать размер блока реже, но большими порциями. Старайтесь вызывать эту процедуру как можно реже, т. к. ей часто не удается заново использовать текущий блок. Кроме того, в процессе увеличения размера блока потери производительности при копировании старых данных в новый блок увеличиваются.
  • Процедура ReallocMem во встроенном менеджере памяти Delphi поддерживает многопотечность, т. е. можно вызывать ReallocMem одновременно из нескольких потоков, но только если переменная IsMultiThread равна True.
  • Встроенный менеджер памяти Delphi предполагает, что программа часто выделяет и освобождает блоки разного размера. Большинство программ соответствуют этому допущению, но не все. Если программа часто вызывает ReallocMem для постепенного увеличения размера большого блока, могут возникнуть проблемы с производительностью и чрезмерным расходом памяти. Решение состоит в том, чтобы либо реже вызывать ReallocMem, либо, если ее частые вызовы необходимы, установить собственный менеджер памяти, который сможет увеличивать размер блока без выделения новых блоков большего размера.

Пример


// Тривиальный список, увеличивающийся пропорционально размерам,
// а не фиксированными шагами.
type
  TObjectArray = array[0..MaxInt div SizeOf(TObject) - 1] of TObject;
  PObjectArray = ^TObjectArray;
  TWholeNumber = 0..MaxInt;
  TArray = class
  private
    fList: PObjectArray;
    fCapacity: TWholeNumber;
    fCount: TWholeNumber;
    procedure Grow;
  public
   constructor Create;
   procedure Add(Obj: TObject);
   procedure Remove(Obj: TObject);
   property Items[Index: TWholeNumber]: TObject
     read GetItem write SetItem;
   property Count: TWholeNumber read fCount;
   property Capacity: TWholeNumber read fCapacity;
  end;

procedure TArray.Add(Obj: TObject);
begin
  if Count = Capacity then Grow;
  fList[Count] := Obj;
  Inc(fCount);
end;

procedure TArray.Grow;
begin
  // Когда размер небольшой, увеличиваем на 100%, иначе - только на 50%.
  if Capacity < 64 then
    fCapacity := Capacity * 2
  else
    fCapacity := Capacity + Capacity div 2;
  ReallocMem(fList, Capacity * SizeOf(TObject));
end;

Смотрите также

Процедуры FreeMem, GetMem, функции ReallocMemory, SysReallocMem.
    Учебник по языку Pascal          Лабораторные работы по программированию          Справочник




Нет комментариев.



Оставить комментарий:
Ваше Имя:
Email:
Антибот: *  
Ваш комментарий: