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 _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal