[fpc-pascal] Why use pointers to arrays?
Tomas Hajny
XHajT03 at mbox.vol.cz
Mon Oct 12 22:47:17 CEST 2009
On 11 Oct 09, at 10:38, Graeme Geldenhuys wrote:
Hi,
.
.
> Anyway to get to my questions, and using the code snippets shown
> below. This code is all based on the code I am porting from
> SpeedPascal. So maybe some strange usage is simply due to the age of
> SpeedPascal etc..
>
>
> ----------------------
> Type
> TLayoutLine = record
> Text: PChar;
> Length: longint;
> Height: longint;
> Width: longint;
> MaxDescender: longint;
> MaxTextHeight: longint;
> LinkIndex: longint;
> Style: TTextDrawStyle;
> Wrapped: boolean;
> end;
>
>
> TLinesArray = array[ 0..0 ] of TLayoutLine;
> --------------------------
>
>
> 1) Why would you use a pointer to an array and not simply a variable
> what IS the array? In the program I am porting the following field
> variable is defined.
>
> FLines: ^TLinesArray;
>
> Why couldn't I simply say:
>
> FLines: TLinesArray;
>
> Is there some advantage for using a pointer to the array, when passing
> it around between procedures and functions?
Yes, there's at least one - you cannot pass (or receive) nil if you
use the array directly. Sometimes the API (e.g. OS API) needs the
possibility to pass or receive nil.
> 2) The TLinesArray is a dynamic array, so shouldn't I maybe change the
> ported code to define the array as follows, instead of the [0..0]
> idea?
>
> TLinesArray = array of TLayoutLine;
Well, it is not a dynamic array strictly speaking, because dynamic
arrays maintain number of elements as part of their definition,
whereas in this case number of elements is kept elsewhere.
> 3) Maybe the strange usage (to me at least) of dynamic arrays could be
> explain in how the original program allocates memory for the array. In
> the class where FLines is defined, it initially reserves ten empty
> elements for the array in the class constructor.
>
> FAllocatedNumLines := 10;
> GetMem( FLines, FAllocatedNumLines * sizeof( TLayoutLine ) );
>
> And then later if it needs more space for elements, it redefines the
> array elements as follows:
>
> Procedure TRichTextLayout.AddLineStart( Const Line: TLayoutLine );
> var
> NewAllocation: longint;
> begin
> if FNumLines >= FAllocatedNumLines then
> begin
> // reallocate the array twice the size
> NewAllocation := FAllocatedNumLines * 2;
> FLines := ReAllocMem(FLines, NewAllocation * sizeof(TLayoutLine));
> FAllocatedNumLines := NewAllocation;
> end;
> FLines^[ FNumLines ] := Line; // ***** (1)
> inc( FNumLines );
> end;
>
>
> Like I said, maybe this is related to different implementations of
> object pascal. By doesn't one allocate memory (array elements) via the
> SetLength() procedure?
> eg:
>
> FAllocatedNumLines := 10;
> SetLength( FLines^, FAllocatedNumLines);
>
>
> I marked on of the lines above with (1). I sometimes get "out of
> range" errors there, so clearly somewhere in all this dereferencing of
> arrays etc, I probably made a mistake somewhere in porting/translating
> the SpeedPascal code to Free Pascal.
Not really, you just use range checking whereas the original code
doesn't. The type definition specifies an array with exactly one
element [0..0], but you access more elements using that type
definition. Technically, there are several ways for such type
definitions, but all of them imply that range checking cannot be used
any longer. The first one is this one. The second would be defining
the upper bound as some very high value (at best as the highest
possible, but even that varies e.g. between 16-bit, 32-bit and 64-bit
CPUs, so it's not portable easily, and it doesn't give you any range
checking either, because although type allows many elements, the real
content has fewer elements and the compiler doesn't know how many).
The third option (using the pointer mathematics and not available in
older Pascal compilers) is declaring the pointer as a pointer to a
single element of that array and accessing it as P[x] (without
dereferencing this pointer; I'd personally tend to use P[x]^, but
that doesn't work, i.e. in this case the pointer isn't a pointer any
longer ;-) ).
Tomas
More information about the fpc-pascal
mailing list