Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>No, I don't think such a thing can happen. It's possible for a string variable to obtain a value that you didn't expect, but it won't leak memory. Consider this:</p> <pre><code>var Global: string; procedure One(const Arg: string); begin Global := ''; // Oops. This is an invalid reference now. Arg points to // what Global used to refer to, which isn't there anymore. writeln(Arg); end; procedure Two; begin Global := 'foo'; UniqueString(Global); One(Global); Assert(Global = 'foo', 'Uh-oh. The argument isn''t really const?'); end; </code></pre> <p>Here <code>One</code>'s argument is declared const, so supposedly, it won't change. But then <code>One</code> circumvents that by changing the actual parameter instead of the formal parameter. Procedure <code>Two</code> "knows" that <code>One</code>'s argument is const, so it expects the actual parameter to retain its original value. The assertion fails.</p> <p>The string hasn't leaked, but this code does demonstrate how you can get a <em>dangling reference</em> for a string. <code>Arg</code> is a local alias of <code>Global</code>. Although we've changed <code>Global</code>, <code>Arg</code>'s value remains untouched, and because it was declared const, the string's reference count was not incremented upon entry to the function. Reassigning <code>Global</code> dropped the reference count to zero, and the string was destroyed. Declaring <code>Arg</code> as var would have the same problem; passing it by value would fix this problem. (The call to <code>UniqueString</code> is just to ensure the string is reference-counted. Otherwise, it may be a non-reference-counted string literal.) All compiler-managed types are susceptible to this problem; simple types are immune.</p> <p>The only way to leak a string is to treat it as something other than a string, or to use non-type-aware memory-management functions. <a href="https://stackoverflow.com/questions/1132561/how-to-leak-a-string-in-delphi/1132662#1132662">Mghie's answer</a> describes how to treat a string as something other than a string by using <code>FillChar</code> to clobber a string variable. Non-type-aware memory functions include <code>GetMem</code> and <code>FreeMem</code>. For example:</p> <pre><code>type PRec = ^TRec; TRec = record field: string; end; var Rec: PRec; begin GetMem(Rec, SizeOf(Rec^)); // Oops. Rec^ is uninitialized. This assignment isn't safe. Rec^.field := IntToStr(4); // Even if the assignment were OK, FreeMem would leak the string. FreeMem(Rec); end; </code></pre> <p>There are two ways to fix it. One is to call <code>Initialize</code> and <code>Finalize</code>:</p> <pre><code>GetMem(Rec, SizeOf(Rec^)); Initialize(Rec^); Rec^.field := IntToStr(4); Finalize(Rec^); FreeMem(Rec); </code></pre> <p>The other is to use type-aware functions:</p> <pre><code>New(Rec); Rec^.field := IntToStr(4); Dispose(Rec); </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload