Recent

Author Topic: Casting dynamic array of char to String fails  (Read 966 times)

Zvoni

  • Jr. Member
  • **
  • Posts: 69
Casting dynamic array of char to String fails
« on: June 13, 2018, 10:26:29 am »
Just encountered something i can't explain to myself.
casting a fixed Array of Char to String works, using the same for dynamic array of char fails.
I did some tests with various functions.
Here's my result.
In particular, Test 4 baffles me completely!
Anyone an idea what's going on?

Code: Pascal  [Select]
  1. program project1;
  2. {$mode objfpc}{$H+}
  3.  
  4. Uses
  5. sysutils, strutils;
  6.  
  7. Var
  8.    sTest:String='<>';
  9.    arrFix:Array[0..1] Of Char;
  10.    arrDyn:Array Of Char;
  11.    sFix:String;
  12.    sDyn:String;
  13.    sPasFix:String;
  14.    sPasDyn:String;
  15. begin
  16.      //Test 1
  17.      arrFix[0]:='<';
  18.      arrFix[1]:='>';
  19.      sFix:=String(arrFix);
  20.      Writeln('sFix: ', sFix, ' - Length: ', Length(sFix));
  21.      //Success!
  22.      If sFix=sTest Then writeln('Success!') Else writeln('Failed!');
  23.  
  24.      //Test 2
  25.      SetLength(arrDyn,Length(sTest));
  26.      arrDyn[0]:='<';
  27.      arrDyn[1]:='>';
  28.      sDyn:=String(arrDyn);
  29.      Writeln('sDyn: ', sDyn, ' - Length: ', Length(sDyn));
  30.      //Failes!
  31.      If sDyn=sTest Then writeln('Success!') Else writeln('Failed!');
  32.  
  33.      //Test 3
  34.      sPasFix:=StrPas(@arrFix[0]);
  35.      Writeln('sPasFix: ', sPasFix, ' - Length: ', Length(sPasFix));
  36.      //Success!
  37.      If sPasFix=sTest Then writeln('Success!') Else writeln('Failed!');
  38.  
  39.      //Test 4
  40.      sPasDyn:=StrPas(@arrDyn[0]);
  41.      //SetLength(sPasDyn,High(arrDyn)+1); //Uncommenting this Line leads to Success
  42.      Writeln('sPasDyn: ', sPasDyn, ' - Length: ', Length(sPasDyn));
  43.      //Failes!
  44.      If sPasDyn=sTest Then writeln('Success!') Else writeln('Failed!');
  45.  
  46.      //Test 5
  47.      SetLength(sPasDyn,High(arrDyn)+1);
  48.      StrCopy(PChar(sPasDyn),@arrDyn[0]);
  49.      Writeln('sPasDyn: ', sPasDyn, ' - Length: ', Length(sPasDyn));
  50.      //Success!
  51.      If sPasDyn=sTest Then writeln('Success!') Else writeln('Failed!');
  52.  
  53.      //Test 6
  54.      SetLength(sPasDyn,High(arrDyn)+1);
  55.      Move(arrDyn[0],sPasDyn[1],High(arrDyn)+1);
  56.      Writeln('sPasDyn: ', sPasDyn, ' - Length: ', Length(sPasDyn));
  57.      //Success!
  58.      If sPasDyn=sTest Then writeln('Success!') Else writeln('Failed!');
  59.  
  60. end.
  61.  
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie

GetMem

  • Hero Member
  • *****
  • Posts: 3256
Re: Casting dynamic array of char to String fails
« Reply #1 on: June 13, 2018, 10:47:50 am »
Use procedure SetString which will set the length of the string, then copies the characters from a buffer.  It will work in both cases:
Code: Pascal  [Select]
  1.  SetString(sDyn, PChar(@arrDyn[0]), Length(arrDyn));
  2.  SetString(sFix, PChar(@arrFix[0]), Length(sFix));
« Last Edit: June 13, 2018, 10:50:21 am by GetMem »

PascalDragon

  • Full Member
  • ***
  • Posts: 206
  • Compiler Developer
Re: Casting dynamic array of char to String fails
« Reply #2 on: June 13, 2018, 10:51:01 am »
@Zvoni: A dynamic array of Char of length X is not the same as a static array of Char with length X. For the later the compiler knows the length at compile time and can insert the required length and #0 character correctly, while it can't do that for a dynamic array. Use the solution mentioned by GetMem if you really need to convert a dynamic array of Char to a string.

Zvoni

  • Jr. Member
  • **
  • Posts: 69
Re: Casting dynamic array of char to String fails
« Reply #3 on: June 13, 2018, 10:57:40 am »
Use procedure SetString which will set the length of the string, then copies the characters from a buffer.  It will work in both cases:
Code: Pascal  [Select]
  1.  SetString(sDyn, PChar(@arrDyn[0]), Length(arrDyn));
  2.  SetString(sFix, PChar(@arrFix[0]), Length(sFix));

Yeah, i know of SetString, since i'm using it.
It just kind of surprised me that there is such a difference between static and dynamic arrays.
Especially, in Test 4, that StrPas seems to copy 7 characters/bytes instead of the expected 2.
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie

Nitorami

  • Sr. Member
  • ****
  • Posts: 346
Re: Casting dynamic array of char to String fails
« Reply #4 on: June 13, 2018, 11:22:35 am »
Test 4:
StrPas() expects a null-terminated string, but your arrDyn is not null-terminated, or only randomly depending on where it has been allocated in memory.