<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#ffffff">
    Here is what happens<br>
    <br>
    <br>
    procedure TfrmFileAssoc.btnAddNewTypeClick(Sender: TObject);<br>
    begin<br>
      edtIconFileName.Text:= TExtAction(Exts.Items[0]).Icon;<br>
    end;<br>
    procedure TfrmFileAssoc.edtIconFileNameChange(Sender: TObject);<br>
    begin<br>
      TExtAction(Exts.Items[0]).Icon := GenName; //DateTimeToStr(Now);<br>
    end;<br>
    <br>
    <br>
    1) btnAddNewTypeClick.<br>
    Takes the string from ExtAction(Exts.Items[0]).Icon;<br>
    This string has a ref-count of 1 (not sure why it shows 2 in your
    debug)<br>
    <br>
    2) SetText(const AValue: String)<br>
    because AValue is constant, it is not expected to change. The
    compiler optimizes the code, the ref-count is not increased. This
    does save the need to insert a hidden try-finally block, which
    otherwhis would be requiredm, to ensure that the refcout was
    decreased at the end of SetText (even if an exception occurred).
    Those implicit tr-finally blocks have a noticeable effect on speed.<br>
    <br>
    3) Going through RealSetText, but then calling you event handler:
    edtIconFileNameChange <br>
    <br>
    4) edtIconFileNameChange <br>
    Releases the string referred to by ExtAction(Exts.Items[0]).Icon;<br>
     => memory is freed<br>
    AValue now points to freed memory => it didn't expect that the
    value was changed.<br>
    <br>
    Since AValue points to freed memory, it will crash on the next
    attempt to use it.<br>
    <br>
    <br>
    ----<br>
    This is actually part of the definition  of "const" for parameters.<br>
    <br>
    const does mean that you as programmer (or in this case the person
    who wrote it) declares that no code anywhere will change the value
    of this variable (which includes calling code)<br>
    <br>
    As a side effect, if using code, the compiler will give you an
    error, if you try to modify it inside that procedure. Because the
    compiler can detect that, and because you promised the compiler not
    to do it.<br>
    But the compiler expects that promise to be kept outside the given
    procedure too.<br>
    <br>
    <br>
    You code does not keep the promise, which some one else made....
    Ouch.<br>
    <br>
    Obviously it could be argued, the LCL should not make such promises.
    It's a decision to be made (and probably to be reviewed now)<br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    On 26/05/2011 22:21, cobines wrote:
    <blockquote
      cite="mid:BANLkTin50TeCCNom+s=X2RZoeW06__ZSzg@mail.gmail.com"
      type="cite">
      <pre wrap="">I have added some debugging text in two functions that set text to a
control: TWinControl.RealSetText and widgetset specific
TWin32WSWinControl.SetText (like in attached diff).

This is a log from execution of a program when it crashes:

TWin32WSWinControl.SetText before 0005FBD8 refcount=2 size=17
TWin32WSWinControl.SetText after  0005FBD8 refcount=2 size=17
TWin32WSWinControl.SetText before 00066D10 refcount=3 size=3
TWin32WSWinControl.SetText after  00066D10 refcount=3 size=3
TWinControl.RealSetText before    00526F18 refcount=-1 size=15
TWin32WSWinControl.SetText before 00526F18 refcount=-1 size=15
TWin32WSWinControl.SetText after  00526F18 refcount=-1 size=15
TWinControl.RealSetText after     00526F18 refcount=-1 size=15
TWinControl.RealSetText before    0007F8A0 refcount=1 size=55
TWin32WSWinControl.SetText before 0007F8A0 refcount=1 size=55
TWin32WSWinControl.SetText after  0007F8A0 refcount=522612 size=0
TWinControl.RealSetText after     0007F8A0 refcount=522612 size=0
TWinControl.RealSetText before    00056A80 refcount=1 size=17
TWin32WSWinControl.SetText before 00056A80 refcount=1 size=17
TWin32WSWinControl.SetText after  00056A80 refcount=355076 size=0
TWinControl.RealSetText after     00056A80 refcount=355076 size=354980

In TWin32WSWinControl.SetText there is corruption of the string record
(but the contents are fine).

Now, if I change
  procedure TControl.SetText(const Value: TCaption);
to
  procedure TControl.SetText(Value: TCaption);

everything is fine:

TWin32WSWinControl.SetText before 0005FBD8 refcount=2 size=17
TWin32WSWinControl.SetText after  0005FBD8 refcount=2 size=17
TWin32WSWinControl.SetText before 00066D10 refcount=3 size=3
TWin32WSWinControl.SetText after  00066D10 refcount=3 size=3
TWinControl.RealSetText before    00526F18 refcount=-1 size=15
TWin32WSWinControl.SetText before 00526F18 refcount=-1 size=15
TWin32WSWinControl.SetText after  00526F18 refcount=-1 size=15
TWinControl.RealSetText after     00526F18 refcount=-1 size=15
TWinControl.RealSetText before    0007F8A0 refcount=2 size=55
TWin32WSWinControl.SetText before 0007F8A0 refcount=2 size=55
TWin32WSWinControl.SetText after  0007F8A0 refcount=1 size=55
TWinControl.RealSetText after     0007F8A0 refcount=1 size=55
TWinControl.RealSetText before    0007F910 refcount=2 size=53
TWin32WSWinControl.SetText before 0007F910 refcount=2 size=53
TWin32WSWinControl.SetText after  0007F910 refcount=1 size=53
TWinControl.RealSetText after     0007F910 refcount=1 size=53

--
cobines
</pre>
      <pre wrap="">
<fieldset class="mimeAttachmentHeader"></fieldset>
--
_______________________________________________
Lazarus mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Lazarus@lists.lazarus.freepascal.org">Lazarus@lists.lazarus.freepascal.org</a>
<a class="moz-txt-link-freetext" href="http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus">http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>