Name

SysFreeMem Function

Syntax

function SysFreeMem(P: Pointer): Integer;

Description

SysFreeMem uses Delphi’s built-in memory manager to free the memory that P points to. It returns zero for success and a non-zero error code if P is invalid or nil.

SysFreeMem is a real function.

Tips and Tricks

  • SysFreeMem is useful if you are writing your own memory manager as a filter and want to call Delphi’s memory manager from your custom memory manager.

  • If you are not implementing a memory manager, use Dispose or FreeMem, not SysFreeMem, to free memory.

  • FreeMem and Dispose already check for a nil pointer, so SysFreeMem doesn’t have to.

Example

// See SetMemoryManager for an explanation of this memory manager.

// Return True if the memory pointed to by PArray is a valid heap block
// and the guard words are intact. Return false for any error.
function GuardsAreOkay(PArray: PIntegerArray; Fill: Boolean): Boolean;
const
  DelphiInUseFlag = 2;
  MemMgrFlags = 7;
var
  Size: LongWord;
begin
  // First get the block size. The size is the long word before
  // the start of the block. Delphi sets the size and stores flags
  // in the 3 LSBits. Delphi's format is subject to change in future
  // releases. The middle bit is set for an allocated block.
  PArray := PIntegerArray(PChar(PArray) - SizeOf(Size));
  Size := PArray[0];
  PArray := PIntegerArray(PChar(PArray) + SizeOf(Size));
  
  if (Size and DelphiInUseFlag) <> DelphiInUseFlag then
  begin
    Result := False;
    Exit;
  end;

  // Remove Delphi's flag from the size, and subtract the size of
  // Delphi's header.
  Size := Size and not MemMgrFlags - SizeOf(Size);

  // Check the guard words.
  if PArray[0] <> AllocatedGuard then
    Result := False

  // The size includes the 2 guard words, so the last guard word
  // is at the size-1 index.
  else if PArray[Size div GuardSize - 1] <> AllocatedGuard then
    Result := False

  else
  begin
    // If we made it this far, the block looks okay.
    Result := True;

    // If the caller requests it (DebugFree does), fill the entire
    // block with the special FreeFill bit pattern, which helps
    // detect problems caused by referring to freed memory.
    if Fill then
      FillChar(PArray^, Size div 2, FreeFill);

    // Change the guard words to FreeGuard even if the caller doesn't
    // want the entire block filled.
    PArray[0] := FreeGuard;
    PArray[Size div GuardSize - 1] := FreeGuard;
  end;
end;

// Return zero for success, non-zero for failure.
function DebugFree(Mem: Pointer): Integer;
var
  PArray: PIntegerArray;
begin
  // Get the pointer to the true start of the memory block.
  PArray := PIntegerArray(PChar(Mem) - GuardSize);

  if not GuardsAreOkay(PArray, True) then
    Result := 1
  else
    Result := SysFreeMem(PArray);
end;

See Also

Dispose Procedure, FreeMem Procedure, FreeMemory Function, GetMemoryManager Procedure, IsMemoryManagerSet Function, IsMultiThread Variable, SetMemoryManager Procedure, SysGetMem Function, SysReallocMem Function, TMemoryManager Type
..................Content has been hidden....................

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