chained pointers 
Author Message
 chained pointers


i'm having a hard time recoding my MOD pattern loader:
each pattern i load the data (properly decoded) on a variable of type

i.e.  var Row : tRow

what i do is pass the row variable on to the pointer, such as this:

patterns^[current_patt]^[current_row]^[current_channel]^ := Row;

but when i reread it i get weird values!
i do a GetMem(patterns, allrows*allchans*allpatts*sizeof(trow)) before
all of this, but the chain of pointers doesn't seem to "hold" the

all data calc'ed in Row is completely OK, it's the passing on to the
pointers which doesn't work.

is it lack of memory (don't think so) or just misorganizing of the

thanks in advance!

Wed, 18 Jun 1902 08:00:00 GMT  
 chained pointers

Hello Brain Power,

I have read your post a dozen times in almost as many days.  I haven't seen any
replies, which seems to indicate that everyone is probably as confused as I am.
After studying your post, I think the root of your problem lies in a poor
understanding of pointers and dynamic arrays.

The two conflicting statements you wrote on which I base my reply are:

>what i do is pass the row variable on to the pointer, such as this:
>patterns^[current_patt]^[current_row]^[current_channel]^ := Row;
>i do a GetMem(patterns, allrows*allchans*allpatts*sizeof(trow)) before
>all of this, but the chain of pointers doesn't seem to "hold" the data!

If you had included the definition for Patterns and tRow you probably would have
received a few replies.  Without the definition for Patterns, we can only guess.
But the two quoted statements would have us believe difference things.  The
first implies that Patterns is a pointer to an array of pointers to an array of
pointers to tRow's.  OTOH the second statement would have us believe that
Patterns is an array of tRow.  

The calculation you make seems to hint that you want to treat Patterns is a
multidimensional array of tRow.  Couple this with the previous statement and it
would seem that the "chained pointers" you refer to in your subject are some
mechanism that you believe would magically compute the runtime subscripts of a
three dimensional dynamic array.  

Sorry to be the bearer of bad news, but except for the slowest moving dimension
(left-most in Turbo Pascal), you cannot allocate a partial multi-dimensioned
array.  To show this, lets consider a two dimensional array. To make the problem
easier to visualize, lets use a specialized array of characters.  Consider an
array of strings.  This structure will appear in memory as a series of strings
laid end-to-end.  The slowest moving dimension references an individual string.
The fastest moving dimension references a character within a string.  

You can easily allocate a dynamic array of strings.  However, you cannot use the
definition if you want to change the size of the strings at runtime.  For
example, if you defined an array of String[255], then the structure would
consist of a series of 256-byte elements (Length Byte + 255-Characeters) laid
end-to-end.  Now consider an array of String[127] occupying the same space.
These shorter strings would appear as a series of 128-byte elements (Length byte
plus 127-Characters) laid end-to-end.  If you used an array of String[255] to
access this structure, then you would only be able to reference every other

Since it is only possible to modify the slowest moving dimension, dynamic arrays
are usually implemented as single dimensioned arrays.  Consider the following.

TYPE  tRow = Array[0..639] of Byte; {- or what ever -}
      tPattern = Array[0..$FFF0 div Sizeof(tRow)-1] of tRow;
      tpPattern = ^tPattern;

VAR   Patterns: tpPattern;
      nPattern: Longint;
      allPatts, allRows, allChans: Integer;
      current_patt, current_row, current_channel: Integer;
      Row: tRow;

    { determine the size of each dimension.  allXXX is the }
    { number of elements, and a dimension is:  0..allXXX-1 }

    { compute the total number of elements needed }
    nPattern := allPatts * LongMul(allRows, allChans);

    {$IFOPT R+}
       If nPattern >= High(Patterns^) Then RunError(201);

    { allocate a suitable single dimensioned array }
    GetMem(Patterns, nPattern * Sizeof(Patterns^[1]));

    { access a dynamic array structured as          }
    { [0..allPatt, 0..allChans, 0..allRows] of tRow }
    Patterns^[current_patt    * allChans * allRows
            + current_channel * allRows
            + current_row] := Row;

The right-most dimension is the easiest to calculate.  It is simply the desired
subscript.  The next dimension to the left has to skip a full block of elements
to its right.  We accomplish this by multiplying the desired subscript by the
total number elements to its right (allRows).  Again we have to do the same for
the next dimension to the left (allChans * allRows).  

Of course you will want to compute and store (allChans * allRows) in a variable
so you won't have to make the multiplication each time.  

You may also want to devise some type of range checking to insure that
current_patt < allPatts, current_row < allRows, and current_channel < allChans.

I hope this helps. If I missed the mark, or failed to present an understandable
explanation, don't hesitate to ask again.  Next time add a little more of the
essential information so we have a better understanding of what you are trying
to accomplish.

Wed, 18 Jun 1902 08:00:00 GMT  
 [ 2 post ] 

 Relevant Pages 

1. pointers, pointers, pointers...

2. Pointers Pointers Pointers

3. Chain-4

4. BP7 protected mode chain to another program

5. Serial Communications interupt chaining.

6. Trouble with interrupt chaining

7. Chaining mouse event handlers in BP7

8. Problem CHAINING to an EXE file

9. Chaining to timer interrupt from protected mode

10. BP7/DOS: Chaining object methods (rather than calling them)

11. Chaining

12. Chaining ISR


Powered by phpBB® Forum Software