Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2023-01

Dynamic array question

3 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Vojtěch Čihák

Hi,
 
is there a way how to have dynamic array "inside" another dynamic array?  
program project1;
{$mode objfpc}{$H+}
 
uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  Classes, SysUtils
  { you can add units after this };
 
{$R *.res}
type
  TDynArray = array of Integer;
  PTDynArray = ^TDynArray;
 
var aArray, aNewArray: TDynArray;
    aNewStart: Integer;
begin
  SetLength(aArray, 300);
  writeln('Length of aArray ', length(aArray));
  aNewStart:=100;
  aArray[aNewStart+5]:=42;
  ;
  aNewArray[5]:=42;
  writeln('Length of aNewArray ', length(aNewArray)); end.      
 
So aNewArray begin at aArray[100] and have length=200 and I could write NewArray[5]:=42; instead of aArray[aNewStart+5]:=42; After all, memory is allocated correctly.
Code above gives "Invalid pointer operation" while this code  
  aNewArray:=PTDynArray(@aArray[aNewStart])^;
 
  aNewArray[5]:=42; 
 
gives "Range check error".
 
Thanks.

Reply by email

Joost van der Sluis
to Vojtěch Čihák

Vojtěch Čihák via fpc-pascal schreef op wo 11-01-2023 om 23:38 [+0100]:

is there a way how to have dynamic array "inside" another dynamic array?

Not in the way you want.

You could define an 'array of array', though. Or an array of records that contain an array.
 

Show quoted text 38 lines
program project1; {$mode objfpc}{$H+}   uses   {$IFDEF UNIX}   cthreads,   {$ENDIF}   Classes, SysUtils   { you can add units after this };   {$R *.res} type   TDynArray = array of Integer;   PTDynArray = ^TDynArray;   var aArray, aNewArray: TDynArray;     aNewStart: Integer; begin   SetLength(aArray, 300);   writeln('Length of aArray ', length(aArray));   aNewStart:=100;   aArray[aNewStart+5]:=42;   ;   aNewArray[5]:=42;   writeln('Length of aNewArray ', length(aNewArray)); end.         So aNewArray begin at aArray[100] and have length=200 and I could write NewArray[5]:=42; instead of aArray[aNewStart+5]:=42; After all, memory is allocated correctly. Code above gives "Invalid pointer operation" while this code     aNewArray:=PTDynArray(@aArray[aNewStart])^;     aNewArray[5]:=42;    gives "Range check error".

The problem is that you make all kind of assumptions about the memory- layout of these arrays, which may not always be valid. Code that works this way might work coincidentally, but may break when switching to another compiler version or by enabling an optimization.

So.. you must really, really have a good reason why you should try this. And if you do so, don't use dynamic types for tricks like this. They are not meant to be used as a a way to map directly into a memory location.

And, in your case, one of the assumptions is wrong. At the start of a dynamic array it's length is stored. That will destroy your memory- layout.

And te compiler will try to allocate/deallocate memory for the second array. One big mess.

You could use a static array for the 'inside' array.

Regards,

Joost.

Reply by email

Vojtěch Čihák
to Joost van der Sluis

Thanks for comprehensive answer. My other code really worked coincidentally. This code:
 
  SetLength(aArray, 400);
  writeln(PInt64(@aArray[0]-8)^);
 
writes out 399.
 
I'll use more conservative code.
 
V.
______________________________________________________________

Show quoted text 5 lines
Od: "Joost van der Sluis via fpc-pascal" Komu: Datum: 12.01.2023 00:22 Předmět: Re: [fpc-pascal] Dynamic array question

Vojtěch Čihák via fpc-pascal schreef op wo 11-01-2023 om 23:38 [+0100]:

is there a way how to have dynamic array "inside" another dynamic array?

Not in the way you want.

You could define an 'array of array', though. Or an array of records that contain an array.
 
The problem is that you make all kind of assumptions about the memory- layout of these arrays, which may not always be valid. Code that works this way might work coincidentally, but may break when switching to another compiler version or by enabling an optimization.

So.. you must really, really have a good reason why you should try this.  And if you do so, don't use dynamic types for tricks like this. They are not meant to be used as a a way to map directly into a memory location.

And, in your case, one of the assumptions is wrong. At the start of a dynamic array it's length is stored. That will destroy your memory- layout.

And te compiler will try to allocate/deallocate memory for the second array. One big mess.

You could use a static array for the 'inside' array.

Regards,

Joost.

Reply by email