Quote:

> Hello.. I'm trying to generate and use dynamic arrays

>in a Turbo Pascal 7 program. I've got the concepts figured

>out, but seeing as Pascal doesn't allow pointer arithmetic, it

>makes things quite a bit more difficult. However, I wrote a

[deription of problem dropped ...red]

Quote:

>Thanks in advance for any help or suggestions.

[pascal code dropped ...red]

Quote:

>-chris gerber

Chris, when working with an untyped two dimensional array, you have

to multiply the first subscript by the number of elements in the

second dimension.

Your calculation:

p := addptr(basep,(i * j) * 2); { point at element in array }

Should be:

p := addptr(basep, ((i * 11{max "I" items} + j) * 2{Size of 1 item};

You also asked for suggestions, so here are a few:

Your AddPtr function is more complex than it needs to be. It could

be simplified as:

Function AddPtr(BaseVal: Pointer; StepVal: integer): Pointer;

Assembler;

asm

les AX, [BaseVal]

add AX, [StepVal]

mov DX, ES

End;

It takes 5 bytes to call a FAR procedure and 5-bytes for this to be

coded as an inline routine, so a library function could be defined

as inline without increasing the size of the program:

Function AddPtr(BaseVal: Pointer; StepVal: integer): Pointer;

INLINE ($59 { pop CX }

/$58 { pop AX }

/$5A { pop DX }

/$03 /$C1 { add AX,CX }

);

You can also do some simple pointer arithmetic by using a little

type casting

p := Ptr(Seg(BaseP^), Ofs(BaseP^) + (i*11 +j) * Sizeof(Integer));

Since you have version 7.0, you can enable extended syntax and let the

compiler do the pointer arithmetic for you. Add {$X+} at the beginning

of the program, define a TYPE tpInteger = ^Integer then use one of the

following;

p := tpInteger(pChar(BaseP) + (i*11+j)*2);

If you define baseP as a pChar then you can drop the pChar type cast.

p := tpInteger(BaseP + (i*11+j)*2);

If you know for certain that the array will be an array of integers

you can define BaseP as a ^Integer then you can drop both type casts.

Note that we no longer have to multiply by 2 or Sizeof(Integer). That

information is now contained in BaseP and properly handled by the 7.0

compiler:

p := BaseP + (i * 11 + j);

Extended syntax also allows use to Inc and Dec pointers.

For example:

p := tpInteger(BaseP); { Or define BaseP and ^Integer }

Inc(p, i * 11 + j); { compiler adjustes for Sizeof(p^) }

{ hence *2 or Sizeof(Integer) dropped }

This lesson on pointer arithmetic is brought to you by the variables i

and j and the pointer p. <g>

Joking aside, I hope this strengthens your understanding and ability

to manipulate pointers. You've got a fair start and the courage to

experiment so I'm sure you'll have it mastered in no time.