char ***pointer;

Wayne A. Throop throopw at xyzzy.UUCP
Fri Nov 18 07:44:07 AEST 1988


> root at mjbtn.MFEE.TN.US (Mark J. Bailey)
> I have declared:
>	char	***pointer;
> Now I know that *ch is generally pointing to the start of a string, ie,
> a list (array) of characters.

Mark has already departed into nonstandard (for C) terminology, and so
I imagine that many (like myself) will be having to guess at what he
really means by his questions.  For example, does he mean that the
expression (*ch) points to the start of a string when the variable ch
is declared as in the example just above?  I suspect not, because it
just isn't true.  Now if something were declared as char *ch, then the
expression (ch) (note: not (*ch)) would point to a character which
could be one of an array of characters.  (Further, in C, when somebody
talks about a "list", they are usually talking about independantly
allocated nodes connected by pointers.  Arrays are called arrays, or
sometimes vectors.  Much, *much* more rarely lists.)

So, to start off, I presume when Mark says "D is a mumble", I presume
he means "The identifier in D, if declared as in D, is a mumble".  That's
how the following makes the most sense.

> **ch would be equal to say a list of lists
> (or an array of strings, ie, **argv, for example).  ***ch would support
> a list of lists of lists of characters.  I suppose this could be associated
> with a two dimensional array of strings.

Well, no.  If declared as char ***ch, ch is not a two dimensional
array of strings, other than in the most abstract, conceptual way.
The object named by ch is a pointer.  The pointer denotes a member of
a one-dimensional array of pointers.  Members of this array of
pointers each denote a member of another (potentially unique)
one-dimentional array of pointers.  Finally, members of this last
array each denote a member of a (potentially unique) one-dimentional
array of characters.

The important thing to note is that the only object for which space is
allocated by the declaration char ***ch is that for the first pointer.
The array of pointers-to-pointers and the arrays of pointers-to-char
and the arrays of characters are all left up to the user to allocate.
Therefore:

> My biggest question here is, when I declare a *ch and then call malloc
> to allocate a space for it to point to, I have a string.  I can ch++ to
> move up the string.  But when I have **ch, and subsequently, ***ch, do
> I have to call malloc to allocate space for more pointers?

Yes, one must allocate all pointers and characters except for ch itself.

> For example (using pointer above),
>    pointer = (char ***) malloc((x)*sizeof(char *));
> to allocate space for the *LIST* of pointers I am wanting to use?

No.  Space is being allocated for items of type (char *), and then
that space is treated as if it were for items of type (char **).
The malloc should, instead, look like this:

    pointer = (char ***) malloc((x)*sizeof(char **));

And, of course, one would then have to allocate space for the second
level of pointers as well as for the character arrays:

    for( i=0; i<SOME_LIMIT; i++ ){
        pointer[i] = (char **) malloc((y)*sizeof(char *));
        for( j=0; j<SOME_OTHER_LIMIT; j++ ){
            pointer[i][j] = (char *) malloc((z)*sizeof(char));
        }
    }

> Can I say **pointer = (char *) newspace?  Then can
> I say **pointer++ to move to then next space?

Depends on what is mean by "then next space".  In the example above,
one can indeed say **pointer = (char *)malloc(mumble); and one can
indeed say **pointer++.  Of course, if p was a pointer typed (char
***) and (pointer==p) before the expression (**pointer++) is
evaluated, then (pointer==(&p[1])) afterwards.  In other words, one
would be starting to step through the allocated arrays in fortran, or
anti-odometer, order instead of C or odometer order.  (Conceptually
speaking, of course, since these aren't multi-dimentional arrays, but
rather collections of uni-dimentional arrays connected by pointers.)

> I also know that *ch can be referenced with ch[] and **ch with
> ch[][].  I assume ***ch can use ch[][][], but is this legal?

Yes, as long as the data structures to which the declaration char ***ch;
refers have been allocated as outlined above.  (And, of course, assuming
that the brackets are filled in with some subscript values, of course.)

> [...] as in
> **pointer++ above.  I guess you could view that as pointer[0][0] going
> to pointer[0][1].

No, that's p[0][0] to p[1][0].  (++) has greater prescedence than (*).

This IS one of those topics that comes by once every few months, so
there is clearly a lot of confusion about how arrays and pointers
relate to each other in C.  The way I keep it straight is to remember
that the declaration

     sometype *p;

is talking about two chunks of storage, one for a pointer, which is
allocated by the declaration, and one for an array of objects of
sometype, which the user must allocate.  On the other hand, the
declaration

     sometype a[SOMESIZE];

is talking about only one chunk of storage, that for an array of
objects of sometype, which the compiler and/or runtime system
allocates.  Then apply the distinction recursively for multiple
dimentions or indirections.

The confusion enters because when (a) is mentioned in an expression,
it usually evaluates to the address of the first element in the chunk
of storage it represents.  Since (p) evaluates to the address of the
first element in the chunk of storage p has been set to point to, this
means that (a) and (p) are often used in exactly the same way in
practice, the difference being that in the (p) case the user must
allocate and free the chunk of memory that is occupied by the array of
sometype objects, and in the (a) case, the compiler takes care of such
things.

Hope this posting is of some help.

--
A is for Atom; they are all so small,
That we have not really seen any at all.

B is for Bomb.  They are much bigger.
So, mister you better keep off of the trigger.
					--- Edward Teller
-- 
Wayne Throop      <the-known-world>!mcnc!rti!xyzzy!throopw



More information about the Comp.lang.c mailing list