Passing pointers to arrays of pointers.... 
Author Message
 Passing pointers to arrays of pointers....

First off, I appoligize for posting to c.l.c AND gnu.g++.help, but
this might apply to either. The error I'm getting is related to
normal C, but the error is coming from g++, so....

Okay, here's the sitch:
I'm reading in lines of a file separated by, say, colons. For later
processing, I've decided to chop it up into the individual fields.
I do this by having an array of pointers to char. As I find each
separator character, I replace it with a terminator and then point
the next available pointer to the next character. For example,
given:

char *ptrarray[MAXFIELDS];

and an input like:

Here's some text:Here's some more:Here's the last<NULL>

It would get parsed like so...

Here's some text<NULL>Here's some more<NULL>Here's the last<NULL>
^                     ^                     ^
\ ptrarray[0]         \ ptrarray[1]         \ ptrarray[2]
  points here           points here           points here

and ptrarray[3] would be set to NULL.

Now, the problem comes when I try to pass this array by pointer to
the function that actually does the parsing. The prototype looks
like so:

int MakePtrArray(char *buffer, char separator, char *(*ptrarray[]));

and the call looks like:

MakePtrArray(buffer,":",&(ptrarray));

And g++ tells me:

incompatible pointer types for argument 3 of
`int MakePtrArray(char *, char, char ***)'

What am I doing wrong here?
--
Joe Emenaker - {*filter*} Engineer | Our infernal mailer daemon has been quite

Linux:"This isn't your father's| 4 lines. However, as you can see, I have
Oldsmo-Unix!" - DON'T finger me| figured out an elegant way to put as many as



Tue, 18 Feb 1997 07:59:47 GMT  
 Passing pointers to arrays of pointers....

   char *ptrarray[MAXFIELDS];
   ...
   int MakePtrArray(char *buffer, char separator, char *(*ptrarray[]));
   ...
   MakePtrArray(buffer,":",&(ptrarray));

   And g++ tells me:

   incompatible pointer types for argument 3 of
   `int MakePtrArray(char *, char, char ***)'

As your function is declared, is accepts arg 3 as an 'array of
pointers to pointers to chars'.  You want a 'pointer to an array
of pointers to chars'.

So, instead of char **ptrarray[], which is equivalent to *(*ptrarray[]),
you want char *(*ptrarray)[].  Perhaps you are confused by the
declaration syntax, yea, it's a bear.  See the FAQ, Q.10.4.

int MakePtrArray(char *buffer, char separator, char *(*ptrarray)[]);

Also, arg 2 (let's count how many other people follow up your
post with this comment) should be a char, and ":" is a string,
or char *.  Single quotes denote character constants, double
quotes strings.

MakePtrArray(buffer,':',&(ptrarray));

   --
   Joe Emenaker - {*filter*} Engineer | Our infernal mailer daemon has been quite

Oo, any job openings? >:-)

Ed Karrels



Tue, 18 Feb 1997 12:48:53 GMT  
 Passing pointers to arrays of pointers....

Quote:

>[I had:]
>int MakePtrArray(char *buffer, char separator, char *(*ptrarray[]));
>    ...
>    char *ptrarray[MAXFIELDS];
>    MakePtrArray(buffer,":",&(ptrarray));
>[The compiler] tells me: incompatible pointer types for argument 3 ...

The type of `ptrarray' is, in cdecl syntax:

        array MAXFIELDS of pointer to char

You compute the address of this array (which thus has type `pointer
to array MAXFIELDS of pointer to char' or `char *(*)[MAXFIELDS]')
and attempt to assign it to a parameter of type `pointer to pointer
to pointer to char' (recall that `array N of T' in a parameter
declaration really means `pointer to T'; here `T' is `pointer to
pointer to char').

Someone else already suggested changing the third parameter's type
to `pointer to array of pointer to char', or `char *(*ptrarray)[]'.
This type is no more useful than `pointer to pointer to char', however,
and instead of passing the address of the entire array, you can
simply pass the address of its first element.

There are only two reason ever to use the type `pointer to array
<etc>'.  The first, and some ways the most legitimate, can only
occur when the <etc> part includes the size of the array.  For
instance:

        cdecl> declare x as pointer to array 5 of int
        int (*x)[5]

Now x can point to the first `array 5 of int' in a linear sequence
of `array 5 of int's, so that you can write `x[i][2]' to get at
the middle int of the i'th such array.

If the size is going to be omitted---for instance, if you will write:

        int (*x)[];

---then x[i][2] is illegal, and `x' is no good for anything except
`*x' (or x[0]).  You are better off using *x originally (e.g., in
the call, replace `&arr' with `*&arr', or more simply `arr'), and
writing `int *x' instead.  (Purists may wish to use `&arr[0]'.)

The only excuse you have for *not* doing this is data hiding.  If
someone hands you an object o of some opaque type T, and commands
you to use &o, you will need a pointer to T.  If T happens to be
an array type and its size is unspecified, you will end up with a
pointer to an array of unknown size (which could be the first of a
linear sequence of such arrays, even though you cannot find them).

This is not a terribly good excuse, because C's handling of arrays
(as `second class citizens'---which makes functions `third class',
in the functional programming sense) makes them a poor choice for
an abstracted or opaque type.  Instead, whoever designs the
abstract/opaque type should use a structure.  This makes objects
of that type behave more like ordinary C objects.  Still, sometimes
you are not the designer, and the poor choice has already been set
in stone.  If you *are* the designer, think!  Structure types, even
apparently-silly ones that contain only a single array or scalar,
may be your best bet, as they offer the most flexibility.

(Someone else also noted that `char' is not suitable for ":".  The
compiler probably should have issued two diagnostics, though there
is no such requirement in the standards.)
--
In-Real-Life: Chris Torek, Berkeley Software Design Inc



Wed, 19 Feb 1997 23:48:48 GMT  
 Passing pointers to arrays of pointers....

Quote:

>    char *ptrarray[MAXFIELDS];
>    ...
>    int MakePtrArray(char *buffer, char separator, char *(*ptrarray[]));
>    ...
>    MakePtrArray(buffer,":",&(ptrarray));
>    And g++ tells me:
>    incompatible pointer types for argument 3 of
>    `int MakePtrArray(char *, char, char ***)'
> As your function is declared, is accepts arg 3 as an 'array of
> pointers to pointers to chars'.  You want a 'pointer to an array
> of pointers to chars'.
> So, instead of char **ptrarray[], which is equivalent to *(*ptrarray[]),
> you want char *(*ptrarray)[].  Perhaps you are confused by the
> declaration syntax, yea, it's a bear.  See the FAQ, Q.10.4.
> int MakePtrArray(char *buffer, char separator, char *(*ptrarray)[]);

Even to complicated to my opinion: If you want to pass a pointer to an
array you should simply pass the name of the array (don't get confused
by what the array contains!):

        MakePtrArray(buffer, ':', ptarray);

That's all! Remember: Whenever the compiler sees the name of an array,
it replaces this name with the value of the adress of the first element.
I.e. arrays are always passed so to say `by reference'.

Now the declaration in the function prototype gets simple and you don't
even have to read the FAQ:

    int MakePtrArray(char * buffer, char separator, char *ptrarray[]);

That's all, honestly. Trust me.

You can find a complete elaborated example of exactly(!) what you're
trying to do on pp. 116 in: "Mike Banahan; The C Book, featuring the    
draft ANSI C standard". I only have a copy of the first printing 1988
and I don't know if there has been a second edition but for me this is
still one of the best books on ANSI-C ever.

Kind regards
        Matthias Froehlich

---------------------------------------------------------------------------
Matthias Froehlich                                   Communication Networks
Aachen UoT                                                     C   O   M
Kopernikusstrasse 16                                        -v-^-v-^-v-^-v-    
52074 Aachen                                                 N   E   T   S

   `If working harder, smarter, and faster won't solve it, what will?'
                                  Stephen R. Covey: First Things First
===========================================================================



Fri, 21 Feb 1997 18:57:53 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Dereferencing f-pointers, arrays of f-pointers, pointers to f-pointers

2. Pointer of Pointers was Pointer of arrays...

3. Pointers: return of pointer to array of pointers to main

4. Array of pointers, pointer to array...

5. array pointer/pointer array

6. arrays pointers array of pointers

7. passing a pointer to a pointer

8. Passing a Pointer to Pointer to an Interface

9. Passing Arrays of Pointers and malloc

10. pass a pointer to a multiple dimension array

11. passing arrays to pointers

12. how to pass an array of char pointers as an argument

 

 
Powered by phpBB® Forum Software