Name

ReallocMem Procedure

Syntax

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

Description

ReallocMem changes the size of a dynamically allocated block, preserving as much of the previous contents as possible.

If P is nil, ReallocMem is just like GetMem. If NewSize is zero, it is just like FreeMem, which means P is not changed, so it contains an invalid pointer after ReallocMem returns.

When possible, ReallocMem tries to adjust the size of the current memory block, but if it cannot, it allocates an entirely new block of the desired size and copies the old data into the new block. In either case, if NewSize is bigger than the current size, the extra memory is not initialized.

ReallocMem is not a real procedure.

Tips and Tricks

  • If you have a block that grows incrementally, anticipate future growth. Instead of frequently increasing the block size in small steps, increase the size by larger steps less often. Try to call ReallocMem as little as possible because ReallocMem often fails to reuse the current block. As the block size grows, the performance penalty for copying the old block to the new block also grows.

  • ReallocMem in Delphi’s default memory manager is thread-safe, that is, you can call ReallocMem from multiple threads simultaneously, but only if IsMultiThread is True.

  • Delphi’s memory manager assumes that the program will frequently allocate and free blocks of varying sizes. Most programs fit this pattern, but a few don’t. If your program often calls ReallocMem to incrementally increase the size of a large block, you might run into performance problems and excessive wasted memory. The solution is to call ReallocMem less often, or if you must call it frequently, substitute your own memory manager that does a better job at increasing a block’s size without needing to allocate new, larger blocks.

Example

// A trivial list that grows by bounds, not steps.
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
  // When small, grow by 100%, when larger grow by only 50%.
  if Capacity < 64 then
    fCapacity := Capacity * 2
  else
    fCapacity := Capacity + Capacity div 2;
  ReallocMem(fList, Capacity * SizeOf(TObject));
end;

See Also

FreeMem Procedure, GetMem Procedure, ReallocMemory Function, SysReallocMem Function
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset