* * *

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

Zvoni

  • Jr. Member
  • **
  • Posts: 56
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.  
People call me crazy because i'm jumping out of perfectly fine airplanes.
I say you're crazy not to!
--------------------------------------------------------------------------------------------------
For health reasons i try to avoid reading unformatted Code

GetMem

  • Hero Member
  • *****
  • Posts: 3108
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: 159
  • 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: 56
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.
People call me crazy because i'm jumping out of perfectly fine airplanes.
I say you're crazy not to!
--------------------------------------------------------------------------------------------------
For health reasons i try to avoid reading unformatted Code

Nitorami

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

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus