Search code examples
delphimemorymemory-managementparametersdelphi-6

Free memory and nil in Delphi using a single function


I have a lot of memory allocations and the same number of FreeMem calls. What I didn't have though is a check before calling freemem to see if the pointer was nil, and a line after freeing to set the pointer to nil.

I tried to create a function to do this

procedure FreeMemAndNil(p: Pointer; size: Integer = -1);
begin
  if p <> nil then
  begin
    if size > -1 then
      FreeMem(p, size)
    else
      FreeMem(p);
    p := nil;
  end;
end;

But there's a problem. It can't set the origional pointer to nil because the parameter isn't variable (var p: Pointer). I can't use var though because if I do the compiler complains the type has to be the exact same type (Pointer). The pointers I'm passing could be pointers to any type (PChar, regular pointer, etc.).

What can I do to fix this? Is there a better solution?


Solution

  • Like Mason Wheeler said you should use the same trick as FreeAndNil in the SysUtils unit does on object references.
    So I modified your code, unit tested it, and this works fine:

    procedure FreeMemAndNil(var ptr; size: Integer = -1);
    var
      p: Pointer;
    begin
      p := Pointer(ptr);
      if p <> nil then
      begin
        if size > -1 then
          FreeMem(p, size)
        else
          FreeMem(p);
        Pointer(ptr) := nil;
      end;
    end;
    

    --jeroen

    PS: Rob Kennedy wrote a nice answer on untyped var parameters that has a link to his untyped parameter page on the internet.

    PS2: For reference: The Kylix version of SysUtils.pas is on-line, and the FreeAndNil there is identical to how it is in Delphi.