A fUnNy StRiNg

CR in his recent post about the quality of Delphi help discussed the StrUpper/StrLower code example. I was interested why the original D7 example causes an access violation while the similar D2009 example runs without AV. So I have written the following tests (in Delphi 2009):

{$WRITEABLECONST OFF}
var
  S1: PChar = 'A fUnNy StRiNg 1';
  S2: string = 'A fUnNy StRiNg 2';
  S3: array[0..20] of Char = 'A fUnNy StRiNg 3';

const
  S4: array[0..20] of Char = 'A fUnNy StRiNg 4';

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;

begin
  S:= S1;
  Canvas.TextOut(5, 10, string(StrLower(PChar(S))));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  S: string;

begin
  S:= S2;
  UniqueString(S);
  Canvas.TextOut(5, 10, string(StrLower(PChar(S))));
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  Canvas.TextOut(5, 10, string(StrLower(S3)));
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  Canvas.TextOut(5, 10, string(StrLower(S4)));
end;

Usually inplace functions like StrUpper/StrLower results in AV because the compiler places string constants in read-only memory. A string should be copied to the heap beforehand. In Button1Click procedure the string copy is made implicitly by assigning PChar to string; in Button2Click procedure one should call UniqueString to create a copy.
But that is not the case with the Button3Click example (which is actually the example from Delphi 2009 help). No copy is created here, still the example runs fine and demonstrates that the static arrays of characters are not placed in read-only memory. More than that, the Button4Click is also OK (I have explicitly included {$WRITEABLECONST OFF} directive, though it is OFF by default, to make the case more clear).

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s