How to include char arrays of pointers in structures 
Author Message
 How to include char arrays of pointers in structures

I need help accomplishing this task.  I am building a database
application with routines I wrote.  I have it working very well
but am stymied on one small thing.

I have defined a global record structure like:

     struct rdata {
     char *database; /* name of database file */
     ... /* other fields */
     char *fields[]; /* this one is the problem */

fields is (supposed to be) a pointer to an array of char pointers
like: char *fields[] = { str.id, str.name, ...};

fields is something I set up at init record time to point to the
actual record structure elements (str) which is set up like:

struct record {
     char id[10];
     char name[30];
     ...
     } str;

The question is; how do I pass a pointer to the field array of
char pointers which in turn point to another structures elements?

When I do it like above I get a warning at compile time that
fields has zero (0) size in struct rdata.  Can I ignore the warning?

All of the above objects are externally defined and declared.

I have battled with this for a long time.  I usually resort to
passing the fields pointer separately which works fine.  I feel
I should be able include that array in the rdata structure.

Thanks for any help in advance.

Tim Brown
Computer Connection
uunet!comcon!tim



Thu, 08 Oct 1992 01:27:36 GMT  
 How to include char arrays of pointers in structures

Quote:

>I have defined a ... structure [including]
[struct rdata {]
>     char *fields[]; /* this one is the problem */
[}]
>fields is (supposed to be) a pointer to an array of char pointers
>like: char *fields[] = { str.id, str.name, ...};

Okay (deep breath): The declaration you gave in no way matches the
English description you gave, and neither one will `do what you want'.

The declaration

        char *fields[];

matches the English (cdecl)

        declare fields as array [ SIZE_UNKNOWN ] of pointer to char

while the English

        declare fields as pointer to array [ SIZE_UNKNOWN ] of pointer
        to char

matches the (essentially useless) C declaration

        char *(*fields)[];
-----
Footnote: I say `essentially useless' because the only excuse for the
type `pointer to array of unknown size of T' (for any suitable type T)
is that `extern T arr[];' declares `arr' as having unknown size, and
hence `&arr' has to have such a type.  The only thing that can be done
with a pointer that points to an array of unknown size is to follow it
to the first (0'th) such array, because the location of the second, third,
fourth, etc., such array is impossible to compute.  In other words, given
        int (*p)[];
the only thing you can `talk about' with `p' is `p[0]', and if you are
going to do that, you might as well write
        int *p0 = p[0];
and then use p0 everywhere.

(One can get into a long discussion of type abstraction here; I would
argue that, at least in C, to do abstraction of this sort, you need to
use structures, not arrays.  Anything else gets too messy.)
-----

Quote:
>fields is something I set up at init record time to point to the
>actual record structure elements (str) which is set up like:

>struct record {
>     char id[10];
>     char name[30];
>     ...
>     } str;

In order to point to zero or more instances of `struct record', `fields'
must have the type `pointer to struct record', i.e.,

        struct record *fields;
        fields = &str;

If instead you meant `fields is supposed to point to a set of pointers,
each of which points to successive elements of a ``struct record'' ',
you would first have to decide on the representation for the set of
pointers, such as `array [ PICK_SOME_SIZE ] of pointer to char':

        char *ptrs[4];
        ptrs[0] = str.id;       /* or ptrs[0] = &str.id[0]; */
        ptrs[1] = str.name;
        ...

If you wish, you can get the compiler to choose the size, in certain
limited circumstances:

        char *ptrs[] = { str.id, str.name };

(Note that the type of `ptrs' here will be `array 2 of pointer to char',
NOT `array SIZE_UNKNOWN of pointer to char'.  I recommend always noting
the size, even if you have to note that you do not know it, or that you
do not need to know it [which is often true].)

You can then make `fields' point to the first (or rather, 0'th) element
of the array `ptrs'.  Because a pointer that points to the first of a
series of contiguous objects (often called `an array') can be used to
access *any one* (at a time) of those objects, this will be useful after
all.  You will have to give fields a type that points to a pointer-to-char:

        char **fields;
        fields = ptrs;

Quote:
>The question is; how do I pass a pointer to the field array of
>char pointers which in turn point to another structures elements?

See above.

Quote:
>When I do it like above I get a warning at compile time that
>fields has zero (0) size in struct rdata.  Can I ignore the warning?

No.
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)



Thu, 08 Oct 1992 23:23:21 GMT  
 How to include char arrays of pointers in structures
|>
|>      struct rdata {
|>      char *database; /* name of database file */
|>      ... /* other fields */
|>      char *fields[]; /* this one is the problem */
|>

Try replacing the last line above with:
        char **fields;





Sat, 10 Oct 1992 00:22:01 GMT  
 How to include char arrays of pointers in structures
 [ ... ]

Quote:
>The declaration

>    char *fields[];

>matches the English (cdecl)

>    declare fields as array [ SIZE_UNKNOWN ] of pointer to char

>while the English

>    declare fields as pointer to array [ SIZE_UNKNOWN ] of pointer
>    to char

>matches the (essentially useless) C declaration

>    char *(*fields)[];
>-----
>Footnote: I say `essentially useless' because the only excuse for the
>type `pointer to array of unknown size of T' (for any suitable type T)
>is that `extern T arr[];' declares `arr' as having unknown size, and
>hence `&arr' has to have such a type.  The only thing that can be done
>with a pointer that points to an array of unknown size is to follow it
>to the first (0'th) such array, because the location of the second, third,
>fourth, etc., such array is impossible to compute.  In other words, given
>    int (*p)[];
>the only thing you can `talk about' with `p' is `p[0]', and if you are
>going to do that, you might as well write
>    int *p0 = p[0];
>and then use p0 everywhere.

I may be missing something here, but here is a small program where I
have declared just such a pointer and there is no problem with indexing
it:

#include <malloc.h>
main()
{
    char *(*ptr)[];
    char *a[10];
    int i;

    for (i = 0; i < 10; i++) {
        a[i] = malloc(sizeof (char));
        *a[i] = i;
    }
    ptr = &a;
    for (i = 0; i < 10; i++) {
        printf("%d\n", *(*ptr)[i]);
    }

Quote:
}

The output is :
0
1
..
9
as expected.  The compiler does give a warning for the assignment "ptr = &a",
but it seems to have no trouble following the pointers.  (I may be
misunderstanding Mr. Torek's statements above, because I don't think I have
ever seen him post something erroneous here).

Roman Rozin



Sat, 10 Oct 1992 07:48:55 GMT  
 How to include char arrays of pointers in structures

Quote:

>>... the only excuse for the
>>type `pointer to array of unknown size of T' (for any suitable type T)
>>is that `extern T arr[];' declares `arr' as having unknown size, and
>>hence `&arr' has to have such a type.  The only thing that can be done
>>with a pointer that points to an array of unknown size is to follow it
>>to the first (0'th) such array, because the location of the second, third,
>>fourth, etc., such array is impossible to compute.  In other words, given
>>        int (*p)[];
>>the only thing you can `talk about' with `p' is `p[0]', and if you are
>>going to do that, you might as well write
>>        int *p0 = p[0];
>>and then use p0 everywhere.

>I may be missing something here, but here is a small program where I
>have declared just such a pointer and there is no problem with indexing
>it:

You have not indexed the pointer, but rather the object to which the
pointer points.  I.e., you are not taking p[i], you are taking p[0][i],
and the simplification I suggested in >> applies:

Quote:
>    char *(*ptr)[];
>    char *a[10];
>    int i;
        ...
>    ptr = &a;

(You should get a diagnostic for this line, even from `ANSI' C compilers,
because the type of &a is (char *(*)[10]), while the type of ptr is
(char *(*)[]), and the numbers in the brackets do not match.)

Quote:
>    for (i = 0; i < 10; i++)
>    printf("%d\n", *(*ptr)[i]);

We can just as easily remove one level of indirection, changing

        let T = pointer to char
        declare ptr as pointer to array [ SIZE_UNKNOWN ] of T
        char *(*ptr)[];

into

        declare ptr0 as pointer to T
        char **ptr0;

and then set ptr0 = *ptr:

        ptr0 = *ptr;    /* or ptr0 = a; */

and then read *ptr0[i]:

        for (i = 0; i < 10; i))
                printf("%d\n", *ptr0[i]);

There is nothing we can do with `ptr' that we cannot do at least as
easily with `ptr0'.
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)



Tue, 13 Oct 1992 05:10:01 GMT  
 How to include char arrays of pointers in structures

Quote:

> I may be missing something here, [...]

Yes.  The point missed was the Chris Torek said that one couldn't
index a pointer of type "pointer to array of unknown size of {any type}".
R Rozin shows that

    char *(*ptr)[];
    [...] *(*ptr)[i]) [...]

works as expected.  But this isn't an example of what Chris was talking
about.  The expression

         ptr[i]

should provoke a compiler complaint.  (Some compilers will simply
and silently take the inter-element-offset of the array to be zero, but
this is not technically correct... it is instead unknown.)

The point is that the declaration

     char *(*ptr)[];

gives no extra utility over the declaration

     char *ptr0[];

(though, of course, the extra indirection needed with the first form
 is not needed with the second).
--



Fri, 16 Oct 1992 10:22:16 GMT  
 How to include char arrays of pointers in structures

Quote:

>(You should get a diagnostic for this ... because the type of &a is
>(char *(*)[10]), while the type of ptr is (char *(*)[]), and the numbers
>in the brackets do not match.)

Norman Diamond has pointed out that the ANSI C standard says otherwise:
a pointer to an incomplete array type (one without a size) is compatible
with a pointer to a complete array type of any size, provided that
the types match when the size is not considered.  In other words,
a pointer of type

        T (*)[]

is compatible with both one of type

        T (*)[10]

and

        T (*)[20] ,

and a pointer of type

        T (*)[3]

is compatible with one of type

        T (*)[] .

This does not, however, affect my original point: there is nothing you
can do with a pointer of type (T (*)[]) that you cannot do with one of
type (T *), except confuse a human reading your code.  (There *is*
something new you can do if you put a number inside the brackets.  This
rule should be applied only to pointers to `sizeless' arrays.)
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)



Sun, 18 Oct 1992 15:30:32 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. A char pointer (char *) vs. char array question

2. char pointer to 2D char array

3. arrays and pointers, char * vs. char [], distinction

4. Differences between char array[SIZE] and char *array

5. How to convert an array of char to a structure

6. An array in a structure Or an Array Of Structures

7. structure containing pointer to char over the network

8. Comparison with pointer to pointer to char, and char

9. Structure pointers, char, and passing

10. Converting char array of literals chars to escape chars

11. cast char array to function pointer?

12. question about array of pointers to chars

 

 
Powered by phpBB® Forum Software