Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Delphi
  4. Need help understanding memory leak [modified]

Need help understanding memory leak [modified]

Scheduled Pinned Locked Moved Delphi
helpdelphihtmlperformancequestion
2 Posts 1 Posters 7 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Member 4187432
    wrote on last edited by
    #1

    Hello! I have some code which leaks memory (it's pretty much copied straight from Rudy's Delphi Corner). I have found the line that which causes the problem, but I don't understand why it's leaking which makes me concerned. I am reluctant to just fix it without knowing what's actually wrong. The purpose of the code is to create a separate copy of a TVarRec variable. Here goes:

    function TfrmMain.CopyVarRec(const Item: TVarRec): TVarRec;
    begin
    // Copy entire TVarRec first.
    Result := Item;

    // Now handle special cases.
    case Item.VType of
    vtExtended:
    begin
    New(Result.VExtended);
    Result.VExtended^ := Item.VExtended^;
    end;
    vtPChar:
    begin
    Result.VPChar := StrNew(Item.VPChar);
    end;
    // A little trickier: casting to string will ensure
    // reference counting is done properly.
    vtAnsiString:
    begin
    // Nil out first, so no attempt to decrement
    // reference count.
    Result.VAnsiString := nil;
    string(Result.VAnsiString) := string(Item.VAnsiString);
    end;
    end;
    end;

    The following function is then used to free the copied TVarRec:

    // TVarRecs created by CopyVarRec must be finalized with this function.
    // You should not use it on other TVarRecs.
    procedure TfrmMain.FinalizeVarRec(var Item: TVarRec);
    begin
    case Item.VType of
    vtExtended: Dispose(Item.VExtended);
    vtString: Dispose(Item.VString);
    // vtAnsiString uses reference counting.
    end;
    Item.VInteger := 0;
    end;

    The above code leaks memory when the TVarRec contains an AnsiString, that is in the vtAnsiString case of the CopyVarRec function. The weird thing is, the memory leak goes away if I remove the line

    Result.VAnsiString := nil;

    before assigning the Item's string to teh string of the the Result. If I remove it, the memory leak goes away and (it appears) the program works fine, but I really don't feel comfortable doing so without understanding why that line causes the problem to begin with. Any ideas? Regards, Daniel

    modified on Monday, April 27, 2009 11:37 AM

    M 1 Reply Last reply
    0
    • M Member 4187432

      Hello! I have some code which leaks memory (it's pretty much copied straight from Rudy's Delphi Corner). I have found the line that which causes the problem, but I don't understand why it's leaking which makes me concerned. I am reluctant to just fix it without knowing what's actually wrong. The purpose of the code is to create a separate copy of a TVarRec variable. Here goes:

      function TfrmMain.CopyVarRec(const Item: TVarRec): TVarRec;
      begin
      // Copy entire TVarRec first.
      Result := Item;

      // Now handle special cases.
      case Item.VType of
      vtExtended:
      begin
      New(Result.VExtended);
      Result.VExtended^ := Item.VExtended^;
      end;
      vtPChar:
      begin
      Result.VPChar := StrNew(Item.VPChar);
      end;
      // A little trickier: casting to string will ensure
      // reference counting is done properly.
      vtAnsiString:
      begin
      // Nil out first, so no attempt to decrement
      // reference count.
      Result.VAnsiString := nil;
      string(Result.VAnsiString) := string(Item.VAnsiString);
      end;
      end;
      end;

      The following function is then used to free the copied TVarRec:

      // TVarRecs created by CopyVarRec must be finalized with this function.
      // You should not use it on other TVarRecs.
      procedure TfrmMain.FinalizeVarRec(var Item: TVarRec);
      begin
      case Item.VType of
      vtExtended: Dispose(Item.VExtended);
      vtString: Dispose(Item.VString);
      // vtAnsiString uses reference counting.
      end;
      Item.VInteger := 0;
      end;

      The above code leaks memory when the TVarRec contains an AnsiString, that is in the vtAnsiString case of the CopyVarRec function. The weird thing is, the memory leak goes away if I remove the line

      Result.VAnsiString := nil;

      before assigning the Item's string to teh string of the the Result. If I remove it, the memory leak goes away and (it appears) the program works fine, but I really don't feel comfortable doing so without understanding why that line causes the problem to begin with. Any ideas? Regards, Daniel

      modified on Monday, April 27, 2009 11:37 AM

      M Offline
      M Offline
      Member 4187432
      wrote on last edited by
      #2

      Alright, I think I figured it out. The line which nils the Result's pointer to the string is needed, because otherwise the code which copies the string will cause the strings reference counter to decrease to 0, freeing the string. This is why the application "stopped" leaking memory when the nil-ing row was removed. Instead, FinalizeVarRec needed to actually set the AnsiString to the empty string too, to make sure the string was freed. I believed taht would be handled by the reference counting, but it doesn't work that way for pointers.

      1 Reply Last reply
      0
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • World
      • Users
      • Groups