Recent

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

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
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 Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

balazsszekely

  • Guest
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

  • Hero Member
  • *****
  • Posts: 5446
  • 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

  • Hero Member
  • *****
  • Posts: 2319
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 Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Nitorami

  • Sr. Member
  • ****
  • Posts: 481
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.

 

TinyPortal © 2005-2018