Array of pointers to arrays?
Author |
Message |
Charles Sulliva #1 / 19
|
 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 |
|
 |
Joona I Palast #2 / 19
|
 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 |
|
 |
Malcol #3 / 19
|
 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 |
|
 |
Charles Sulliva #4 / 19
|
 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 |
|
 |
Mathew Hendr #5 / 19
|
 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 |
|
 |
Mathew Hendr #6 / 19
|
 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 |
|
 |
Charles Sulliva #7 / 19
|
 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 |
|
 |
Charles Sulliva #8 / 19
|
 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 |
|
 |
Barry Schwar #9 / 19
|
 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 |
|
 |
Barry Schwar #10 / 19
|
 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 |
|
 |
Sobh #11 / 19
|
 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 |
|
 |
Richard Heathfiel #12 / 19
|
 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 |
|
 |
Chris Tore #13 / 19
|
 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 |
|
 |
Chris Tore #14 / 19
|
 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 |
|
 |
Richard Heathfiel #15 / 19
|
 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? 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 |
|
|
Page 1 of 2
|
[ 19 post ] |
|
Go to page:
[1]
[2] |
|