Recent

Author Topic: Pointer to array questions  (Read 4022 times)

PeterHu

  • Jr. Member
  • **
  • Posts: 62
Pointer to array questions
« on: August 01, 2025, 03:47:19 pm »
I am trying to get familar with freepascal basic concepts,now I am stuck with the pointer to array (both static and dynamic).

Please see below full code which can be compiled.My questions are as shown in the comments.

Help would be appreciated.

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. {$codepage utf8}{$H+}{$J-}
  3.  
  4. type
  5.   tdynarray = array of byte;
  6.   pdynarray=^tdynarray;
  7.  
  8. var
  9.   regulararray: array[0..3] of byte;
  10.   pregulararray:pPointerarray;
  11.  
  12.   barr:tdynarray;
  13.   pbarr:pdynarray;
  14.  
  15.   p:pbyte;
  16.   ptr:pointer;
  17.  
  18.   i:integer;
  19.  
  20. begin
  21.   regulararray[0]:=9;
  22.   regulararray[1]:=1;
  23.   regulararray[2]:=2;
  24.   regulararray[3]:=3;
  25.  
  26.   pregulararray:=@regulararray;
  27.  
  28.   p:=@regulararray;
  29.   ptr:=@regulararray;
  30.   writeln((p+2)^);
  31.  
  32.   // 1. The compiler warns this is not portable,
  33.   // then what's the corect way to get the address?
  34.   writeln(nativeInt(ptr));
  35.  
  36.   writeln((pbyte(pregulararray)+2)^);
  37.   writeln(pbyte(ptr+3)^);
  38.  
  39.   writeln('-------------------------');
  40.   readln;
  41.  
  42.   setlength(barr,10);
  43.   for i:=0 to 9 do begin
  44.     barr[i]:=i*10+1;
  45.         end;
  46.  
  47.   for i:=0 to 9 do begin
  48.     writeln(barr[i]);
  49.         end;
  50.   writeln;
  51.  
  52.   pbarr:=@barr;
  53.   for i:=0 to 9 do begin
  54.    // 2. why it should be (pbarr]^[i],other than (pbarr+i)^ ,or (pbarr[i])^ ?
  55.     (pbarr)^[i]:=i*10+10;
  56.         end;
  57.  
  58.   for i:=0 to 9 do begin
  59.     writeln(barr[i]);
  60.         end;
  61.  
  62.   readln;
  63.  
  64.   {
  65.   p=@barr;  // 3.why the compiler says this is an illegal expression ?
  66.   for i:=0 to 9 do begin
  67.     (p+i)^:=i*10+100;
  68.         end;
  69.  
  70.   for i:=0 to 9 do begin
  71.     writeln(barr[i]);
  72.         end;
  73.   }
  74.   readln;
  75. end.                      
  76.  
  77.  
  78.  
  79.  
« Last Edit: August 01, 2025, 03:56:47 pm by PeterHu »

Thaddy

  • Hero Member
  • *****
  • Posts: 18792
  • Glad to be alive.
Re: Pointer to array questions
« Reply #1 on: August 01, 2025, 04:01:38 pm »
The pointer to an array content is always a pointer the the first item and that is the case with fixed arrays AND dynamic arrays'
So: given
Array[0..3] of byte or DynArr array of byte =(0,1,2,3);

The pointer is always:@[0];

Exception: Fixed arrays with indices not starting from 0: there it is @[Low(array)];

As your code shows, there are other ways to get at the values, but the above is guaranteed to work.
Also make sure you know which packing settings are used, otherwise it becomes difficult to use pointer type array access.
In my opinion really bad programming anyway, C'ísms. You are using Pascal, NOT C, take advantage of it.
There is almost never a need for code such as you present.
« Last Edit: August 01, 2025, 04:10:20 pm by Thaddy »
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

PeterHu

  • Jr. Member
  • **
  • Posts: 62
Re: Pointer to array questions
« Reply #2 on: August 02, 2025, 01:24:09 am »
The pointer to an array content is always a pointer the the first item and that is the case with fixed arrays AND dynamic arrays'
So: given
Array[0..3] of byte or DynArr array of byte =(0,1,2,3);

The pointer is always:@[0];

Exception: Fixed arrays with indices not starting from 0: there it is @[Low(array)];

As your code shows, there are other ways to get at the values, but the above is guaranteed to work.
Also make sure you know which packing settings are used, otherwise it becomes difficult to use pointer type array access.
In my opinion really bad programming anyway, C'ísms. You are using Pascal, NOT C, take advantage of it.
There is almost never a need for code such as you present.

Thanks for the help. I am not loving to do so in C way,just wan to make clear in concept how does pointer in freepascal doing ,and how to write correct code with pointers in free pascal.
« Last Edit: August 02, 2025, 02:10:42 am by PeterHu »

jamie

  • Hero Member
  • *****
  • Posts: 7602
Re: Pointer to array questions
« Reply #3 on: August 02, 2025, 02:20:59 am »
Wanted to add some fluff here.

Managed strings are also pointers however, to get to the very first char in the string you need to specify 1
but, that is a language specific and could change to 0 as the first one when using [ x ] to index the string in that style.

  You can however type cast a managed string like this

 Pchar(MyString) and that is at the start of the string too, since the string actually starts at 0 offset but the compiler offsets it to 1 when indexing it via MyString[ x ]. Just language specific and could change with an option to keep with the other guy !

 In sort, using [ x ] on mystring is basically an index offset from a pointer that is generated.

Also keep in mind that you can have an array of pointers in which case then you need to adda ^ to indicate you want to branch to that memory pointed to via the [ x ]^ etc.

Jamie





The only true wisdom is knowing you know nothing

PeterHu

  • Jr. Member
  • **
  • Posts: 62
Re: Pointer to array questions
« Reply #4 on: August 02, 2025, 04:59:04 am »
Wanted to add some fluff here.

Managed strings are also pointers however, to get to the very first char in the string you need to specify 1
but, that is a language specific and could change to 0 as the first one when using [ x ] to index the string in that style.

  You can however type cast a managed string like this

 Pchar(MyString) and that is at the start of the string too, since the string actually starts at 0 offset but the compiler offsets it to 1 when indexing it via MyString[ x ]. Just language specific and could change with an option to keep with the other guy !

 In sort, using [ x ] on mystring is basically an index offset from a pointer that is generated.

Also keep in mind that you can have an array of pointers in which case then you need to adda ^ to indicate you want to branch to that memory pointed to via the [ x ]^ etc.

Jamie

This is helpful,thank you!

Now knowing below is wrong:
Code: Pascal  [Select][+][-]
  1. var
  2.    str:string;
  3.   pstr:^string;
  4. begin
  5.    str:='This is a string';  
  6.    pstr:=@str;
  7.    writeln(pstr^[0]);//Error: Element zero of an ansi/wide- or longstring cannot be accessed, use (set)length instead
  8.  

We can do this:
Code: Pascal  [Select][+][-]
  1.   pstr:=@str;
  2.   writeln(pstr^);
  3.   writeln(pstr^[1]);
  4.   writeln(length(str));  //16
  5.   writeln(length(pstr^));
  6.   setlength(str,33);
  7.   writeln(length(pstr^));
  8.   fillchar(str[17],16,'@');
  9.   writeln(str);
  10.   writeln(pstr^);
  11.   fillchar((pstr^[17]),16,'#');
  12.   writeln(pstr^);
  13.   pstr^[33]:='!';
  14.   writeln(pstr^[33]);
  15.   writeln(str);
  16.   writeln(str[33]);
  17.   writeln(pstr^);    
  18.  
  19.  
« Last Edit: August 02, 2025, 05:25:00 am by PeterHu »

jamie

  • Hero Member
  • *****
  • Posts: 7602
Re: Pointer to array questions
« Reply #5 on: August 02, 2025, 06:23:59 pm »
managed strings store the length information prior to the address given to your app.

so, this means you need to use the pointer giving to you minus some bytes to obtain the header information.

You can find the information in the sources of how the header is formatted.

Also, using short strings, which are not managed strings, the length indicator is at index 0 whereas the first character is at index 1.

 Those are limited to 255 chars plus one byte for the length but can be statically defined to any length up to 255.

 MyShortString:String[ 10 ]; results in a string 10 characters long plus the length string which makes it 11 bytes in memory.

 lengths are not calculated via a Null (#0) character with strings; however, you can cast the string to a Pchar of sorts and then the #0 will indicate the end of the string.

 Manage strings allows #0 (null) characters as a valid part of the string so this means you can in theory use it for binary storage.

Jamie

The only true wisdom is knowing you know nothing

PeterHu

  • Jr. Member
  • **
  • Posts: 62
Re: Pointer to array questions
« Reply #6 on: August 03, 2025, 05:16:47 am »
managed strings store the length information prior to the address given to your app.

so, this means you need to use the pointer giving to you minus some bytes to obtain the header information.

You can find the information in the sources of how the header is formatted.

Also, using short strings, which are not managed strings, the length indicator is at index 0 whereas the first character is at index 1.

 Those are limited to 255 chars plus one byte for the length but can be statically defined to any length up to 255.

 MyShortString:String[ 10 ]; results in a string 10 characters long plus the length string which makes it 11 bytes in memory.

 lengths are not calculated via a Null (#0) character with strings; however, you can cast the string to a Pchar of sorts and then the #0 will indicate the end of the string.

 Manage strings allows #0 (null) characters as a valid part of the string so this means you can in theory use it for binary storage.

Jamie

Here are my weak point in freepascal basic concept as well,thank you again.Things seem to be a bit compilcated now...

Do you mean information like this:https://wiki.freepascal.org/AnsiString

PascalDragon

  • Hero Member
  • *****
  • Posts: 6355
  • Compiler Developer
Re: Pointer to array questions
« Reply #7 on: August 03, 2025, 01:25:48 pm »
I am trying to get familar with freepascal basic concepts,now I am stuck with the pointer to array (both static and dynamic).

Please see below full code which can be compiled.My questions are as shown in the comments.

For 1: This is the correct way to do this conversion, however the NativeUInt type is declared an an alias to the corresponding base type of the correct size for a pointer and thus for the compiler this type is in no way special and thus it needs to warn, because the pointer size might be different on a different platform. There is no built-in type that automatically matches the size of a pointer and thus there is no way to circumvent the compiler's message here.

For 2: The difference between a static array and a dynamic array is that a dynamic array variable itself already is a pointer. So for a static array a pointer to the first element of the array and to the variable itself is the same, but for a dynamic array a pointer to the first element of the array is different from a pointer to the variable. So you need to do another dereferenciation or better yet: don't use pointers with dynamic arrays at all.

For 3: This immediately follows the explanation for 2: a pointer to a dynamic array is a pointer to a dynamic array and not a pointer to the first element and thus you can't assign that to a PByte in your specific case.

Thaddy

  • Hero Member
  • *****
  • Posts: 18792
  • Glad to be alive.
Re: Pointer to array questions
« Reply #8 on: August 03, 2025, 01:40:44 pm »
Basically the same as my previous answer.
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6355
  • Compiler Developer
Re: Pointer to array questions
« Reply #9 on: August 03, 2025, 02:07:06 pm »
Your answer contains no information about a pointer to a dynamic array variable being different from a pointer to the first element.

jamie

  • Hero Member
  • *****
  • Posts: 7602
Re: Pointer to array questions
« Reply #10 on: August 03, 2025, 03:31:39 pm »
reminds me of C/C++, Pointers to Pointers ** etc.  :D

Jamie


Wanted to add.
   We do have PtrUint/UintPtr conversions that seem to be able to determine the size within your code on the fly.

« Last Edit: August 03, 2025, 03:36:18 pm by jamie »
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 18792
  • Glad to be alive.
Re: Pointer to array questions
« Reply #11 on: August 03, 2025, 04:09:36 pm »
Your answer contains no information about a pointer to a dynamic array variable being different from a pointer to the first element.
What I meant to explain is that whatever the array type, when you need a pointer to its content, take the pointer to the first element. @a[Low(a)].
The low() is only necessary for fixed arrays that do not start from zero.  Dynamic arrays always start at a[0];
But you can use that for both types.
« Last Edit: August 03, 2025, 04:21:36 pm by Thaddy »
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

Thaddy

  • Hero Member
  • *****
  • Posts: 18792
  • Glad to be alive.
Re: Pointer to array questions
« Reply #12 on: August 03, 2025, 04:24:52 pm »
Your answer contains no information about a pointer to a dynamic array variable being different from a pointer to the first element.
What I meant to explain is that whatever the array type, when you need a pointer to its content, take the pointer to the first element. @a[Low(a)].
The low() is only necessary for fixed arrays that do not start from zero.  Dynamic arrays always start at a[0];
But you can use Low() for both types.
Recovered from removal of tumor in tongue following tongue reconstruction with a part from my leg.

PeterHu

  • Jr. Member
  • **
  • Posts: 62
Re: Pointer to array questions
« Reply #13 on: August 04, 2025, 09:28:08 am »
I am trying to get familar with freepascal basic concepts,now I am stuck with the pointer to array (both static and dynamic).

Please see below full code which can be compiled.My questions are as shown in the comments.

For 1: This is the correct way to do this conversion, however the NativeUInt type is declared an an alias to the corresponding base type of the correct size for a pointer and thus for the compiler this type is in no way special and thus it needs to warn, because the pointer size might be different on a different platform. There is no built-in type that automatically matches the size of a pointer and thus there is no way to circumvent the compiler's message here.

For 2: The difference between a static array and a dynamic array is that a dynamic array variable itself already is a pointer. So for a static array a pointer to the first element of the array and to the variable itself is the same, but for a dynamic array a pointer to the first element of the array is different from a pointer to the variable. So you need to do another dereferenciation or better yet: don't use pointers with dynamic arrays at all.

For 3: This immediately follows the explanation for 2: a pointer to a dynamic array is a pointer to a dynamic array and not a pointer to the first element and thus you can't assign that to a PByte in your specific case.

Thank you,this helps a lot.

PeterHu

  • Jr. Member
  • **
  • Posts: 62
Re: Pointer to array questions
« Reply #14 on: August 04, 2025, 09:32:32 am »
Your answer contains no information about a pointer to a dynamic array variable being different from a pointer to the first element.
What I meant to explain is that whatever the array type, when you need a pointer to its content, take the pointer to the first element. @a[Low(a)].
The low() is only necessary for fixed arrays that do not start from zero.  Dynamic arrays always start at a[0];
But you can use Low() for both types.

ha~,comparing index 0 or index N, index low(a) is the thing helps me a lot but I really overlook.Thanks!

 

TinyPortal © 2005-2018