Array of pointers to arrays? 
Author Message
 Array of pointers to arrays?

Newbie question:

How can I declare an array of pointers to fixed-length char arrays such
that I can access any particular one of these char arrays with code
such as in this example:

/* Reserve space for 200 names, each a maximum of 15 characters in length */
char *names[200] = ??? ;

void store_names ( ... ) {
{
   extern char *names[];  

   ...
   (void) strcpy(names[7], "Harry");
   (void) strcpy(names[8], "Pete");

   ...
   return;

Quote:
}

Thanks for your help.

Regards,
Charles Sullivan



Sat, 05 Feb 2005 02:03:11 GMT  
 Array of pointers to arrays?

Quote:
> Newbie question:
> How can I declare an array of pointers to fixed-length char arrays such
> that I can access any particular one of these char arrays with code
> such as in this example:

An array of M pointers to arrays of N characters:
char (*array[M])[N];

Quote:
> /* Reserve space for 200 names, each a maximum of 15 characters in length */
> char *names[200] = ??? ;

You don't appear to need pointers at all in this case. Why not simply an
array of 200 arrays of 15 characters?

char names[200][15];

Quote:
> void store_names ( ... ) {
> {
>    extern char *names[];  

This should be extern char names[][15];

Quote:
>    ...
>    (void) strcpy(names[7], "Harry");
>    (void) strcpy(names[8], "Pete");

This should then work. BTW you don't need the (void) cast. Computing a
value that you never use is perfectly legal in C.

Quote:
>    ...
>    return;
> }

--

| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste       W++ B OP+                     |
\----------------------------------------- Finland rules! ------------/
"Stronger, no. More seductive, cunning, crunchier the Dark Side is."
   - Mika P. Nieminen


Sat, 05 Feb 2005 02:19:30 GMT  
 Array of pointers to arrays?

Quote:

> Newbie question:

> How can I declare an array of pointers to fixed-length char arrays such
> that I can access any particular one of these char arrays with code
> such as in this example:

> /* Reserve space for 200 names, each a maximum of 15 characters in length
*/
> char *names[200] = ??? ;

char names[200][16] = { "Fred1", "Fred2" ... etc };


Sat, 05 Feb 2005 02:30:00 GMT  
 Array of pointers to arrays?

Quote:


>> Newbie question:

>> How can I declare an array of pointers to fixed-length char arrays such
>> that I can access any particular one of these char arrays with code
>> such as in this example:

> An array of M pointers to arrays of N characters: char (*array[M])[N];

That looks like it ought to work, but the compiler (gcc 2.96) still complains
if, within the function, I declare "extern char *array[]", which is what
I primarily wanted to do.  I expected to be able to do this with only
a simple declaration (like you've mentioned above), but maybe not.

Quote:
>> /* Reserve space for 200 names, each a maximum of 15 characters in
>> length */ char *names[200] = ??? ;

> You don't appear to need pointers at all in this case. Why not simply an
> array of 200 arrays of 15 characters?

> char names[200][15];

Agreed, that works. But my primary objective was to find out whether
I could use "extern char *names[]" within the function along with
some simple declaration to allocate the arrays pointed to and store the
pointers at compile time.

Quote:
>> void store_names ( ... ) {
>> {
>>    extern char *names[];

> This should be extern char names[][15];

>>    ...
>>    (void) strcpy(names[7], "Harry");
>>    (void) strcpy(names[8], "Pete");

> This should then work. BTW you don't need the (void) cast. Computing a
> value that you never use is perfectly legal in C.

Agreed, it's legal, but I've understood that void-casting non-void
functions like this is (or was) considered "good form".  If not, I'll
be very happy to stop doing it since it does (IMO) adversely impact
the readability of the code.

Thanks for your response.

Regards,
Charles Sullivan



Sat, 05 Feb 2005 08:37:49 GMT  
 Array of pointers to arrays?
On Mon, 19 Aug 2002 18:03:11 GMT, Charles Sullivan

Quote:

>How can I declare an array of pointers to fixed-length char arrays such
>that I can access any particular one of these char arrays with code
>such as in this example:

>/* Reserve space for 200 names, each a maximum of 15 characters in length */
>char *names[200] = ??? ;

Your code does not match your initial question. You say you want to
allocate an array of pointers, but from the code it appears that you
want to allocate an array of pointers *and* something for those
pointers to point at. You can't do both in one fell swoop. You could
use

  #define COUNT 200
  #define LEN (15+1) /* +1 for '\0' terminator */

  /* array of array */
  char names_storage[COUNT][LEN];

  /* array of pointer to array */
  char (*names[COUNT][LEN];

  /* call this function before using ''names'' */
  void init_names(void)
  {
    int index;
    for (index = 0; index < COUNT; ++index)
      names[n] = &names_storage[n];
  }

This is rather cumbersome, and unnecessary unless for some reason you
need to "repoint" the pointers at something else. Simpler would be to
use

  char names[COUNT][LEN];

and work from there.

-- Mat.



Sat, 05 Feb 2005 09:24:27 GMT  
 Array of pointers to arrays?
On Tue, 20 Aug 2002 02:24:27 +0100, Mathew Hendry

Quote:

>...
>  #define COUNT 200
>  #define LEN (15+1) /* +1 for '\0' terminator */

>  /* array of array */
>  char names_storage[COUNT][LEN];

>  /* array of pointer to array */
>  char (*names[COUNT][LEN];

Oops, I dropped a parenthesis; should read

   char (*names[COUNT])[LEN];

Quote:
>...

-- Mat.


Sat, 05 Feb 2005 09:27:12 GMT  
 Array of pointers to arrays?

Quote:


>> Newbie question:

>> How can I declare an array of pointers to fixed-length char arrays such
>> that I can access any particular one of these char arrays with code
>> such as in this example:

>> /* Reserve space for 200 names, each a maximum of 15 characters in
>> length
> */
>> char *names[200] = ??? ;

> char names[200][16] = { "Fred1", "Fred2" ... etc };

My simple example falsely implied that I know the contents
of the arrays at compile time, which is not the case.  Sorry.

To reword my question:
Is it possible to write a declaration which, at compile time, will both
allocate memory for fixed-length character arrays and pre-assign values
in an array of pointers to those arrays, such that the specific declaration
within a function "extern char *names[]" will allow me to write to the
character arrays pointed to by the pointers in names[].

Note:
If I do something like this:
char *names[] = {"                  ", "               ", (etc) };

and then attempt to write to those arrays, I get a seg fault.  I assume
this compiler is locating the arrays in a protected segment and it's
probably a compiler-dependant action.



Sat, 05 Feb 2005 09:16:07 GMT  
 Array of pointers to arrays?

Quote:

> On Tue, 20 Aug 2002 02:24:27 +0100, Mathew Hendry

>>...
>>  #define COUNT 200
>>  #define LEN (15+1) /* +1 for '\0' terminator */

>>  /* array of array */
>>  char names_storage[COUNT][LEN];

>>  /* array of pointer to array */
>>  char (*names[COUNT][LEN];

> Oops, I dropped a parenthesis; should read

>    char (*names[COUNT])[LEN];

>>...

> -- Mat.

Thanks Mat.  Somehow I thought doing this would be a natural
for C language, but I guess not.

Incidentally, I tried your "cumbersome" code and it doesn't seem
quite right either.  Perhaps it's just this compiler (gcc), but
it doesn't recognize the array declared:
  char (*array[COUNT])[LEN];

as an array of pointers to character arrays, to the extent that the
compiler issues a warning about incompatible pointer types
for subsequent lines of code like:
  strcpy(array[k], "abcdefg");

Regards,
Charles Sullivan



Sat, 05 Feb 2005 10:42:31 GMT  
 Array of pointers to arrays?
On Tue, 20 Aug 2002 01:16:07 GMT, Charles Sullivan

Quote:

>My simple example falsely implied that I know the contents
>of the arrays at compile time, which is not the case.  Sorry.

>To reword my question:
>Is it possible to write a declaration which, at compile time, will both
>allocate memory for fixed-length character arrays and pre-assign values
>in an array of pointers to those arrays, such that the specific declaration
>within a function "extern char *names[]" will allow me to write to the
>character arrays pointed to by the pointers in names[].

If you are willing to accept that you cannot change the pointers, only
what they point to, and if you know how many pointers you need (this
should be the same as the maximum number of char arrays you will
process), and if you know the maximum length each char array will be,
then you can use
        char names[max_ptr_quantity][max_array_len];

This will allocate sufficient space for all the arrays.  While it does
not create any pointers as such, the expression names[i] will, in most
cases, be converted by the compiler to the address of the first
element of the i-th array, namely &names[i][0], with the correct type
(char*).

You can use this expression in almost any context you could have used
the pointers you originally asked for.  The one major exception being
on the left side of an assignment statement, hence the initial
limitation I started with.

In other translation units, you can use
        extern char names[max_ptr_quantity][max_array_len];
and they will also be able to use the notation described above.

Quote:

>Note:
>If I do something like this:
>char *names[] = {"                  ", "               ", (etc) };

>and then attempt to write to those arrays, I get a seg fault.  I assume
>this compiler is locating the arrays in a protected segment and it's
>probably a compiler-dependant action.

Your assumption is correct but it is not really compiler dependent.
In this example, each pointer points to a string literal.  String
literals are, by definition, non-modifiable arrays of char.
Therefore, you should be treat them as const, even though the standard
and your compiler do not.

<<Remove the del for email>>



Sat, 05 Feb 2005 11:34:29 GMT  
 Array of pointers to arrays?
On Tue, 20 Aug 2002 02:42:31 GMT, Charles Sullivan

Quote:


>> On Tue, 20 Aug 2002 02:24:27 +0100, Mathew Hendry

>>>...
>>>  #define COUNT 200
>>>  #define LEN (15+1) /* +1 for '\0' terminator */

>>>  /* array of array */
>>>  char names_storage[COUNT][LEN];

>>>  /* array of pointer to array */
>>>  char (*names[COUNT][LEN];

>> Oops, I dropped a parenthesis; should read

>>    char (*names[COUNT])[LEN];

>>>...

>> -- Mat.

>Thanks Mat.  Somehow I thought doing this would be a natural
>for C language, but I guess not.

>Incidentally, I tried your "cumbersome" code and it doesn't seem
>quite right either.  Perhaps it's just this compiler (gcc), but
>it doesn't recognize the array declared:
>  char (*array[COUNT])[LEN];

This declares array as an array of COUNT pointer to array of LEN char.
Therefore array[i] is one particular pointer to array of LEN char.
array[i] is not a pointer to char.

Quote:

>as an array of pointers to character arrays, to the extent that the
>compiler issues a warning about incompatible pointer types
>for subsequent lines of code like:
>  strcpy(array[k], "abcdefg");

strcpy requires both parameters to be char*.  array[k] is not of the
correct type.  You could cast it to the correct type (since it has the
correct address) or use the equivalent &array[k][0].

<<Remove the del for email>>



Sat, 05 Feb 2005 11:48:03 GMT  
 Array of pointers to arrays?

Quote:

> > Newbie question:

> > How can I declare an array of pointers to fixed-length char arrays such
> > that I can access any particular one of these char arrays with code
> > such as in this example:

> An array of M pointers to arrays of N characters:
> char (*array[M])[N];

> > /* Reserve space for 200 names, each a maximum of 15 characters in length */
> > char *names[200] = ??? ;

> You don't appear to need pointers at all in this case. Why not simply an
> array of 200 arrays of 15 characters?

The need of array of pointers is to save memory rather to put
it into two dimensional arrays..If the characters of name is less
than 15 then the whole memory is getting waste..
Quote:

> char names[200][15];

> > void store_names ( ... ) {
> > {
> >    extern char *names[];  

> This should be extern char names[][15];

> >    ...
> >    (void) strcpy(names[7], "Harry");
> >    (void) strcpy(names[8], "Pete");

> This should then work. BTW you don't need the (void) cast. Computing a
> value that you never use is perfectly legal in C.

> >    ...
> >    return;
> > }



Sat, 05 Feb 2005 13:09:02 GMT  
 Array of pointers to arrays?

Quote:

<snip>

> My simple example falsely implied that I know the contents
> of the arrays at compile time, which is not the case.  Sorry.

> To reword my question:
> Is it possible to write a declaration which, at compile time, will both
> allocate memory for fixed-length character arrays and pre-assign values
> in an array of pointers to those arrays, such that the specific declaration
> within a function "extern char *names[]" will allow me to write to the
> character arrays pointed to by the pointers in names[].

Whoa! That's a tight spec. Strictly speaking, it's not possible. In
practice, there is often a way, if you are prepared to forego strict ISO
conformance.

char foo[6][6] =
{
  "Hello",
  "World",
  "What",
  "a",
  "Wonderful",
  "day"

Quote:
};

char *bar[6] =
{
  foo[0], foo[1], foo[2], foo[3], foo[4], foo[5], foo[6]

Quote:
};

But if you were prepared to do that, you probably wouldn't be asking
here.

Of course, there's nothing (except your spec) to stop you doing the
second part in a loop *after* the declaration, in which case it would be
legal C.

If it's any help, I wouldn't do it the way you're trying to do it. For a
start, I wouldn't be using extern char *[].

Quote:
> Note:
> If I do something like this:
> char *names[] = {"                  ", "               ", (etc) };

> and then attempt to write to those arrays, I get a seg fault.  I assume
> this compiler is locating the arrays in a protected segment and it's
> probably a compiler-dependant action.

You should always treat string literals as read-only. The Standard does
not permit you to write into them. Whether implementations let you write
into them is more or less up to each individual implementation (and your
doing so constitutes undefined behaviour, removing any obligation on
your implementation to do sensible things from that point on).

--

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton



Sat, 05 Feb 2005 14:45:01 GMT  
 Array of pointers to arrays?


Quote:
>Newbie question:
>How can I declare an array of pointers to fixed-length char arrays ...

As a rule, a "newbie question" about "pointers to arrays" suggests
that the newbie has not yet grokked "The Rule". :-)

Why do you believe you require such pointers, each of which points
to an entire array?  Note in particular that a pointer that points
only to a single "char" can still be used to access the entire array
of "char"s:

    char buf[SIZE];
    char *p = buf;

While "p" points only *to* one "char", C guarantees that it
points to the first of "SIZE" sequential such "char"s.  If
SIZE is, say, 20, you can then do:

    strcpy(p, "supercalifragialist");

with complete safety (but do note that the complete word,
"supercalifragialisticexpialidocious", will NOT fit; only the first
SIZE-1 characters, plus the terminating '\0', fit).

The only thing you gain by pointing to an array is the ability
to access subsequent *arrays*.  For instance:

    char buf[5][SIZE];
    char (*p)[SIZE] = buf;

Now p[0] names the *entire array* that is also named buf[0], and
p[1] names the *entire array* that is also named buf[1], and so
on.  Each of these entire arrays, being array objects, undergo the
transformation specified by The Rule in value contexts, so that
p[i][j] names exactly the same single "char" as buf[i][j].

In C, the crucial difference between a pointer to a single object
and a pointer to an array is really the "size of the circle" you
would draw around the target of a pointer, if you were drawing
objects (as I did in <http://67.40.109.61/torek/c/pa.html>).  The
circle tells you how the pointer will react to pointer arithmetic,
which in turn lets you understand subscripting (once you realize
when and how arrays "decay", as the informal expression goes, into
pointers via The Rule).
--
In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)





Sat, 05 Feb 2005 15:56:00 GMT  
 Array of pointers to arrays?

Quote:

>> To reword my question:
>> Is it possible to write a declaration which, at compile time, will both
>> allocate memory for fixed-length character arrays and pre-assign values
>> in an array of pointers to those arrays, such that the specific declaration
>> within a function "extern char *names[]" will allow me to write to the
>> character arrays pointed to by the pointers in names[].



Quote:
>Whoa! That's a tight spec. Strictly speaking, it's not possible.

I think you are making an assumption (perhaps a correct one) that
is not stated above.  The assumption is that the number of
"strings" (for want of a better word) is to be specified exactly
once, e.g., in the initializer for the array of arrays of char:

Quote:
>In practice, there is often a way, if you are prepared to forego
>strict ISO conformance.

>char foo[6][6] = {
>  "Hello",
>  "World",
>  "What",
>  "a",
>  "Wonderful",
>  "day"
>};

>char *bar[6] = {
>  foo[0], foo[1], foo[2], foo[3], foo[4], foo[5], foo[6]
>};

You have one too many initializers for "bar", there is no foo[6],
and "Wonderful" is too long ("Wonder" fits but omits a final '\0',
which may also be undesirable).  Fixing these, however, gives
what I believe can be strictly conforming code.  In particular,
intializers for static objects have fairly wide latitude, and it
is OK to take the address of some other object:

    static int a;
    static int *b = &a;

is always legal.

The only real problem here is that you must know in advance that
there are exactly 6 "target strings", as it were.

Incidentally, note that if the name "foo" is not going to be used
elsewhere, this can be written as:

    static char foo[36] =
        { "Hello\0World\0What\0\0a\0\0\0\0\0Wonderday\0\0\0" };
    char *bar[6] =
        { &foo[0], &foo[6], &foo[12], &foo[18], &foo[24], &foo[30] };

This method is somewhat more error-prone -- can you guarantee I
have counted each "string" correctly within the array "foo"? --
but illustrates precisely what happens "under the hood", as it
were.  It is also probably more useful if we make bar[] slightly
bigger and add a NULL pointer at the end:

    char *bar[7] =
        { &foo[0], &foo[6], &foo[12], &foo[18], &foo[24], &foo[30], NULL };

If this kind of thing *is* what is desired, it may be reasonable
to write a C program to produce a C translation unit containing
the initialized array, then run that program on a source file
containing the desired strings.  This program can verify that all
the strings fit in the alloted space (5 or 6 characters above,
depending on interpretation), count them, produce the array "foo"
(correctly initialized with no counting mistakes), and produce the
array "bar" (or "names"), also correctly initialized.

Finally, note that if we *do* use this, there is no obvious indication
other than initializer for "foo" that there are only six characters
available in each position found via bar[i].  This presents ample
opportunities for future mistakes.  For instance, printing bar[5]
with print's "%s" format will output "Wonderday", rather than
"Wonder".  You must use "%.6s" to limit printf's action, leaving
the reader of the printf() call to, ah, wonder: "why 6?"
--
In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)





Sat, 05 Feb 2005 17:05:37 GMT  
 Array of pointers to arrays?

Quote:


> >> To reword my question:
> >> Is it possible to write a declaration which, at compile time, will both
> >> allocate memory for fixed-length character arrays and pre-assign values
> >> in an array of pointers to those arrays, such that the specific declaration
> >> within a function "extern char *names[]" will allow me to write to the
> >> character arrays pointed to by the pointers in names[].



> >Whoa! That's a tight spec. Strictly speaking, it's not possible.

> I think you are making an assumption (perhaps a correct one) that
> is not stated above.  The assumption is that the number of
> "strings" (for want of a better word) is to be specified exactly
> once, e.g., in the initializer for the array of arrays of char:

Fair enough - how else might you interpret it?

- Show quoted text -

Quote:

> >In practice, there is often a way, if you are prepared to forego
> >strict ISO conformance.

> >char foo[6][6] = {
> >  "Hello",
> >  "World",
> >  "What",
> >  "a",
> >  "Wonderful",
> >  "day"
> >};

> >char *bar[6] = {
> >  foo[0], foo[1], foo[2], foo[3], foo[4], foo[5], foo[6]
> >};

> You have one too many initializers for "bar", there is no foo[6],
> and "Wonderful" is too long ("Wonder" fits but omits a final '\0',
> which may also be undesirable).

EEK! Sorry about those two foul-ups. I must have been distracted by how
wonderful a day it's turning out to be to be to be to be to be to
b$&&*.o)!"((%17

Quote:
> Fixing these, however, gives
> what I believe can be strictly conforming code.  In particular,
> intializers for static objects have fairly wide latitude, and it
> is OK to take the address of some other object:

>     static int a;
>     static int *b = &a;

> is always legal.

But, in my (flawed) example above, foo is not static. Is

int a;
static int *b = &a;

legal? I don't think so. On exit from the first call of the function,
all else being equal, b's value would become indeterminate and would not
regain a determinate value on re-entry to the function later on.

Quote:
> The only real problem here is that you must know in advance that
> there are exactly 6 "target strings", as it were.

Actually, I think the principal problem here is that we have not been
given the opportunity to offer better solutions involving, perhaps,
dynamic data structures, because the OP has phrased his question in such
a way that we don't know the real problem he's trying to solve. *Why*
has he placed these seemingly arbitrary restraints on the design?

<snip>

--

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton



Sat, 05 Feb 2005 18:50:16 GMT  
 
 [ 19 post ]  Go to page: [1] [2]

 Relevant Pages 

1. array of pointers to array of structs

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

3. array pointer/pointer array

4. arrays pointers array of pointers

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

6. pointers to an array and accesing elements of the array

7. Copy Array string to another Pointer array string in ANSI-C

8. convert list to array, arrays of pointers (to strings)

9. 2D array of pointers to 2D arrays

10. declaring an array of pointers to malloced arrays

11. qsorting & managing struct arrays, pointer arrays

12. pointer to array not recognised as array?

 

 
Powered by phpBB® Forum Software