Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #101737 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2017-01-14 04:16 -0800 |
| Last post | 2017-01-15 12:55 -0800 |
| Articles | 20 on this page of 27 — 10 participants |
Back to article view | Back to comp.lang.c
sizeof(x) / sizeof(x[0]) Alla _ <modelling.data@gmail.com> - 2017-01-14 04:16 -0800
Re: sizeof(x) / sizeof(x[0]) "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-14 04:27 -0800
Re: sizeof(x) / sizeof(x[0]) Alla _ <modelling.data@gmail.com> - 2017-01-14 04:43 -0800
Re: sizeof(x) / sizeof(x[0]) "Fernando D. Bozzo" <fdbozzo@gmail.com> - 2017-01-14 04:52 -0800
Re: sizeof(x) / sizeof(x[0]) Alla _ <modelling.data@gmail.com> - 2017-01-14 06:10 -0800
Re: sizeof(x) / sizeof(x[0]) Keith Thompson <kst-u@mib.org> - 2017-01-14 15:55 -0800
Re: sizeof(x) / sizeof(x[0]) jt@toerring.de (Jens Thoms Toerring) - 2017-01-14 13:13 +0000
Re: sizeof(x) / sizeof(x[0]) Alla _ <modelling.data@gmail.com> - 2017-01-15 22:23 -0800
Re: sizeof(x) / sizeof(x[0]) Keith Thompson <kst-u@mib.org> - 2017-01-16 08:58 -0800
Re: sizeof(x) / sizeof(x[0]) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-14 14:47 +0000
Re: sizeof(x) / sizeof(x[0]) Alla _ <modelling.data@gmail.com> - 2017-01-14 07:17 -0800
Re: sizeof(x) / sizeof(x[0]) Manfred <noname@invalid.add> - 2017-01-14 16:22 +0100
Re: sizeof(x) / sizeof(x[0]) Barry Schwarz <schwarzb@dqel.com> - 2017-01-14 08:35 -0800
Re: sizeof(x) / sizeof(x[0]) Alla _ <modelling.data@gmail.com> - 2017-01-15 22:53 -0800
Re: sizeof(x) / sizeof(x[0]) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-16 15:58 +0000
Re: sizeof(x) / sizeof(x[0]) Alla _ <modelling.data@gmail.com> - 2017-01-16 22:38 -0800
Re: sizeof(x) / sizeof(x[0]) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-17 10:11 +0000
Re: sizeof(x) / sizeof(x[0]) James Kuyper <jameskuyper@verizon.net> - 2017-01-14 11:43 -0500
Re: sizeof(x) / sizeof(x[0]) Keith Thompson <kst-u@mib.org> - 2017-01-14 16:01 -0800
Re: sizeof(x) / sizeof(x[0]) Alla _ <modelling.data@gmail.com> - 2017-01-16 01:36 -0800
Re: sizeof(x) / sizeof(x[0]) Barry Schwarz <schwarzb@dqel.com> - 2017-01-16 09:47 -0800
Re: sizeof(x) / sizeof(x[0]) James Kuyper <jameskuyper@verizon.net> - 2017-01-16 21:12 -0500
Re: sizeof(x) / sizeof(x[0]) Alla _ <modelling.data@gmail.com> - 2017-01-16 22:29 -0800
Re: sizeof(x) / sizeof(x[0]) Les Cargill <lcargill99@comcast.com> - 2017-01-14 14:27 -0600
Re: sizeof(x) / sizeof(x[0]) Keith Thompson <kst-u@mib.org> - 2017-01-14 15:52 -0800
Re: sizeof(x) / sizeof(x[0]) Lőrinczy Zsigmond <nospam@for.me> - 2017-01-15 20:20 +0100
Re: sizeof(x) / sizeof(x[0]) Keith Thompson <kst-u@mib.org> - 2017-01-15 12:55 -0800
Page 1 of 2 [1] 2 Next page →
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-14 04:16 -0800 |
| Subject | sizeof(x) / sizeof(x[0]) |
| Message-ID | <1420cd8f-e5cb-4a8f-93e6-d80a8b050650@googlegroups.com> |
Hello!
Please, read my explanation before answering, to show
my mistake.
Honestly, for some time now I was sure I have no problems
with the statement sizeof(x) / sizeof(x[0]), usually used as
the macro to compute the size of an array of strings. I was
positive that I know how it works, and didn't doubt.
Somehow today when I used this macro again I've experienced
a confusion - how does it work, and what have I completely
forgotten? Although shameful, I have decided to come here again
for help on this matter.
For example:
char *array[] = {"abc", "defg", "hijklmop", NULL};
The pointer points to an array that has 4 strings.
sizeof(x) here will be sizeof(array) thus indicating
the size in bytes of the whole array of strings,
because 'array' here is used as the address of the
first sub-element, which is 'a' (array is the same as
array[0][0]);
so sizeof(array) will give the number of bytes occupied
by the whole array of strings, i.e. number
of characters x 1 (which is the size of a char);
the denominator sizeof(x[0]) gives the size of the
first element of the array, i.e. the size of the first
string, which is here "abc", so it it is 3 (3 characters,
each 1 byte); and all other strings have different
number of characters in them, and hence different
number of bytes;
how then sizeof(x) / sizeof(x[0]) gives a correct number
of strings in the array (it actually does, I have tested it
on different strings)? Please, show me my mistake.
Thank you!
[toc] | [next] | [standalone]
| From | "Fernando D. Bozzo" <fdbozzo@gmail.com> |
|---|---|
| Date | 2017-01-14 04:27 -0800 |
| Message-ID | <ae7bd432-5100-43df-8501-ae4f8e4f8f5e@googlegroups.com> |
| In reply to | #101737 |
El sábado, 14 de enero de 2017, 13:16:37 (UTC+1), Alla _ escribió:
> Hello!
>
> Please, read my explanation before answering, to show
> my mistake.
> Honestly, for some time now I was sure I have no problems
> with the statement sizeof(x) / sizeof(x[0]), usually used as
> the macro to compute the size of an array of strings. I was
> positive that I know how it works, and didn't doubt.
> Somehow today when I used this macro again I've experienced
> a confusion - how does it work, and what have I completely
> forgotten? Although shameful, I have decided to come here again
> for help on this matter.
>
> For example:
> char *array[] = {"abc", "defg", "hijklmop", NULL};
> The pointer points to an array that has 4 strings.
> sizeof(x) here will be sizeof(array) thus indicating
> the size in bytes of the whole array of strings,
> because 'array' here is used as the address of the
> first sub-element, which is 'a' (array is the same as
> array[0][0]);
>
> so sizeof(array) will give the number of bytes occupied
> by the whole array of strings, i.e. number
> of characters x 1 (which is the size of a char);
>
> the denominator sizeof(x[0]) gives the size of the
> first element of the array, i.e. the size of the first
> string, which is here "abc", so it it is 3 (3 characters,
> each 1 byte); and all other strings have different
> number of characters in them, and hence different
> number of bytes;
>
> how then sizeof(x) / sizeof(x[0]) gives a correct number
> of strings in the array (it actually does, I have tested it
> on different strings)? Please, show me my mistake.
>
> Thank you!
Hi:
How is related "x" to "array"? Can you post how are you assigning x?
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-14 04:43 -0800 |
| Message-ID | <388bc5e2-01fd-49a3-8814-9e438d1ae07c@googlegroups.com> |
| In reply to | #101740 |
On Saturday, January 14, 2017 at 3:27:34 PM UTC+3, Fernando D. Bozzo wrote:
> El sábado, 14 de enero de 2017, 13:16:37 (UTC+1), Alla _ escribió:
> > Hello!
> >
> > Please, read my explanation before answering, to show
> > my mistake.
> > Honestly, for some time now I was sure I have no problems
> > with the statement sizeof(x) / sizeof(x[0]), usually used as
> > the macro to compute the size of an array of strings. I was
> > positive that I know how it works, and didn't doubt.
> > Somehow today when I used this macro again I've experienced
> > a confusion - how does it work, and what have I completely
> > forgotten? Although shameful, I have decided to come here again
> > for help on this matter.
> >
> > For example:
> > char *array[] = {"abc", "defg", "hijklmop", NULL};
> > The pointer points to an array that has 4 strings.
> > sizeof(x) here will be sizeof(array) thus indicating
> > the size in bytes of the whole array of strings,
> > because 'array' here is used as the address of the
> > first sub-element, which is 'a' (array is the same as
> > array[0][0]);
> >
> > so sizeof(array) will give the number of bytes occupied
> > by the whole array of strings, i.e. number
> > of characters x 1 (which is the size of a char);
> >
> > the denominator sizeof(x[0]) gives the size of the
> > first element of the array, i.e. the size of the first
> > string, which is here "abc", so it it is 3 (3 characters,
> > each 1 byte); and all other strings have different
> > number of characters in them, and hence different
> > number of bytes;
> >
> > how then sizeof(x) / sizeof(x[0]) gives a correct number
> > of strings in the array (it actually does, I have tested it
> > on different strings)? Please, show me my mistake.
> >
> > Thank you!
>
> Hi:
>
> How is related "x" to "array"? Can you post how are you assigning x?
Here is the macro (I have not posted it assuming people know it, sorry):
#define ARRAY_SIZE(x) ( sizeof(x) / sizeof(x[0]) )
[toc] | [prev] | [next] | [standalone]
| From | "Fernando D. Bozzo" <fdbozzo@gmail.com> |
|---|---|
| Date | 2017-01-14 04:52 -0800 |
| Message-ID | <201446a6-fb70-4e5a-b5ed-fca27d9c8551@googlegroups.com> |
| In reply to | #101743 |
El sábado, 14 de enero de 2017, 13:43:16 (UTC+1), Alla _ escribió: <snip> > Here is the macro (I have not posted it assuming people know it, sorry): > #define ARRAY_SIZE(x) ( sizeof(x) / sizeof(x[0]) ) Oh, surely all people here knows this, but I'm new :)
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-14 06:10 -0800 |
| Message-ID | <ae27a11c-ba52-4aba-ae71-cf57b3ff5928@googlegroups.com> |
| In reply to | #101745 |
On Saturday, January 14, 2017 at 3:52:21 PM UTC+3, Fernando D. Bozzo wrote: > El sábado, 14 de enero de 2017, 13:43:16 (UTC+1), Alla _ escribió: > <snip> > > Here is the macro (I have not posted it assuming people know it, sorry): > > #define ARRAY_SIZE(x) ( sizeof(x) / sizeof(x[0]) ) > > Oh, surely all people here knows this, but I'm new :) oops ) Sorry ) But, anyway, I assume you know much more than I do; my messages are considered sort of an eyesore here, and I am grateful for a lot of people who still help me ) I am sure you will enjoy this group.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-14 15:55 -0800 |
| Message-ID | <ln4m11i4d4.fsf@kst-u.example.com> |
| In reply to | #101745 |
"Fernando D. Bozzo" <fdbozzo@gmail.com> writes:
> El sábado, 14 de enero de 2017, 13:43:16 (UTC+1), Alla _ escribió:
> <snip>
>> Here is the macro (I have not posted it assuming people know it, sorry):
>> #define ARRAY_SIZE(x) ( sizeof(x) / sizeof(x[0]) )
>
> Oh, surely all people here knows this, but I'm new :)
That's certainly a reasonable definition for that macro, but since
there's no such macro in the standard it is important to be explicit.
Minor variations in how it's defined could be significant.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2017-01-14 13:13 +0000 |
| Message-ID | <edumfuF7genU1@mid.uni-berlin.de> |
| In reply to | #101737 |
Alla _ <modelling.data@gmail.com> wrote:
> Honestly, for some time now I was sure I have no problems
> with the statement sizeof(x) / sizeof(x[0]), usually used as
> the macro to compute the size of an array of strings. I was
> positive that I know how it works, and didn't doubt.
> Somehow today when I used this macro again I've experienced
> a confusion - how does it work, and what have I completely
> forgotten? Although shameful, I have decided to come here again
> for help on this matter.
>
> For example:
> char *array[] = {"abc", "defg", "hijklmop", NULL};
> The pointer points to an array that has 4 strings.
> sizeof(x) here will be sizeof(array) thus indicating
> the size in bytes of the whole array of strings,
> because 'array' here is used as the address of the
> first sub-element, which is 'a' (array is the same as
> array[0][0]);
> so sizeof(array) will give the number of bytes occupied
> by the whole array of strings, i.e. number
> of characters x 1 (which is the size of a char);
> the denominator sizeof(x[0]) gives the size of the
> first element of the array, i.e. the size of the first
> string, which is here "abc", so it it is 3 (3 characters,
> each 1 byte); and all other strings have different
> number of characters in them, and hence different
> number of bytes;
> how then sizeof(x) / sizeof(x[0]) gives a correct number
> of strings in the array (it actually does, I have tested it
> on different strings)? Please, show me my mistake.
The whole thing works for all kinds of arrays, not
just for "arrays of strings" (which is a name that
is a bit problemtic, see below). So better start of
with something simpler, e.g. an array of ints:
int x[] = {1, 2, 3, 4};
As you write, sizeof(x) is the number of bytes this
array occupies. And sizeof(x[0]) (or sizeof(x[1])
as well) gives you the size in bytes of one of the
elements of the array. Dividing them gives you the
number of elements of the array 'x', obviously.
What you call an "array of strings"
char *x[] = {"abc", "defg", "hijklmop", NULL};
is actually an array of char pointers. Due to the
initialization its first three elements are set to
point to "string literals" (i.e. strings that you
can't modify and for which the compiler reserved
memory somewhere in the data part of the program),
and the last element isn't even anything like a
string, but a NULL pointer (remember, a string is
nothing but a char array that contains a '\0' cha-
racter somewhere).
Now sizeof(x[0]) is the size of one of these ele-
ments, i.e. the size of a char pointer. And if you
divide sizeof(x) by sizeof(x[0]) you again get the
number of elements of this array, i.e. how many
char pointers you can store in that array. If all
the pointers point to strings you could loosely
say that it's the number of strings stored in that
array. But better always keep in mind that there are
no strings stored in it butmerely char pointers. And
these pointers not necessarily point to strings, with
e.g.
char c1 = 'a', c2 = 'b', c3 = 'c';
char *x[] = {&c1, &c2, &c3, NULL};
'x' is also an array of char pointers, but non of
its elements point to strings. So calling it an
array of strings would be extremely misleading.
Also: make sure that you only try to use this
"trick" in cases where the array is defined in
the scope where you use it! E.g. this
static void foo(int *y) {
printf("%d", (int) (sizeof(y) / sizeof(y[0])));
}
int main(void) {
int x[] = {1, 2, 3, 4};
foo(x);
return 0;
}
will fail! The reason is that nothing in function
foo() "knows" that the argument 'y' it received
is pointing to an array, so in that function
sizeof(y) is just the size of an int pointer, not
the size of the array 'x' you defined in main().
And thus the result of dividing it by the size of
an int is nothing that would make much sense.
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-15 22:23 -0800 |
| Message-ID | <c17aad24-fddc-4ef9-a0e2-16d5f7716292@googlegroups.com> |
| In reply to | #101748 |
On Saturday, January 14, 2017 at 4:13:43 PM UTC+3, Jens Thoms Toerring wrote:
> Alla _ <modelling.data@gmail.com> wrote:
> > Honestly, for some time now I was sure I have no problems
> > with the statement sizeof(x) / sizeof(x[0]), usually used as
> > the macro to compute the size of an array of strings. I was
> > positive that I know how it works, and didn't doubt.
> > Somehow today when I used this macro again I've experienced
> > a confusion - how does it work, and what have I completely
> > forgotten? Although shameful, I have decided to come here again
> > for help on this matter.
> >
> > For example:
> > char *array[] = {"abc", "defg", "hijklmop", NULL};
> > The pointer points to an array that has 4 strings.
> > sizeof(x) here will be sizeof(array) thus indicating
> > the size in bytes of the whole array of strings,
> > because 'array' here is used as the address of the
> > first sub-element, which is 'a' (array is the same as
> > array[0][0]);
>
> > so sizeof(array) will give the number of bytes occupied
> > by the whole array of strings, i.e. number
> > of characters x 1 (which is the size of a char);
>
> > the denominator sizeof(x[0]) gives the size of the
> > first element of the array, i.e. the size of the first
> > string, which is here "abc", so it it is 3 (3 characters,
> > each 1 byte); and all other strings have different
> > number of characters in them, and hence different
> > number of bytes;
>
> > how then sizeof(x) / sizeof(x[0]) gives a correct number
> > of strings in the array (it actually does, I have tested it
> > on different strings)? Please, show me my mistake.
>
> The whole thing works for all kinds of arrays, not
> just for "arrays of strings" (which is a name that
> is a bit problemtic, see below). So better start of
> with something simpler, e.g. an array of ints:
>
> int x[] = {1, 2, 3, 4};
>
> As you write, sizeof(x) is the number of bytes this
> array occupies. And sizeof(x[0]) (or sizeof(x[1])
> as well) gives you the size in bytes of one of the
> elements of the array. Dividing them gives you the
> number of elements of the array 'x', obviously.
>
> What you call an "array of strings"
>
> char *x[] = {"abc", "defg", "hijklmop", NULL};
>
> is actually an array of char pointers. Due to the
> initialization its first three elements are set to
> point to "string literals" (i.e. strings that you
> can't modify and for which the compiler reserved
> memory somewhere in the data part of the program),
> and the last element isn't even anything like a
> string, but a NULL pointer (remember, a string is
> nothing but a char array that contains a '\0' cha-
> racter somewhere).
>
> Now sizeof(x[0]) is the size of one of these ele-
> ments, i.e. the size of a char pointer. And if you
> divide sizeof(x) by sizeof(x[0]) you again get the
> number of elements of this array, i.e. how many
> char pointers you can store in that array. If all
> the pointers point to strings you could loosely
> say that it's the number of strings stored in that
> array. But better always keep in mind that there are
> no strings stored in it butmerely char pointers. And
> these pointers not necessarily point to strings, with
> e.g.
>
> char c1 = 'a', c2 = 'b', c3 = 'c';
> char *x[] = {&c1, &c2, &c3, NULL};
>
> 'x' is also an array of char pointers, but non of
> its elements point to strings. So calling it an
> array of strings would be extremely misleading.
>
> Also: make sure that you only try to use this
> "trick" in cases where the array is defined in
> the scope where you use it! E.g. this
>
> static void foo(int *y) {
> printf("%d", (int) (sizeof(y) / sizeof(y[0])));
> }
>
> int main(void) {
> int x[] = {1, 2, 3, 4};
> foo(x);
> return 0;
> }
>
> will fail! The reason is that nothing in function
> foo() "knows" that the argument 'y' it received
> is pointing to an array, so in that function
> sizeof(y) is just the size of an int pointer, not
> the size of the array 'x' you defined in main().
> And thus the result of dividing it by the size of
> an int is nothing that would make much sense.
>
Thank you very much for this explanation. It is very
clear. Unfortunately, as I have not used this macro
for quite a while, I have completely forgotten (as I have
mentioned in my reply to Ben) that the denominator
has a pointer as its arguments. Thank you.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-16 08:58 -0800 |
| Message-ID | <ln8tqbeycl.fsf@kst-u.example.com> |
| In reply to | #101921 |
Alla _ <modelling.data@gmail.com> writes:
[...]
>> Alla _ <modelling.data@gmail.com> wrote:
>> > For example:
>> > char *array[] = {"abc", "defg", "hijklmop", NULL};
[...]
> Thank you very much for this explanation. It is very
> clear. Unfortunately, as I have not used this macro
> for quite a while, I have completely forgotten (as I have
> mentioned in my reply to Ben) that the denominator
> has a pointer as its arguments. Thank you.
In the macro
#define ARRAY_LEN(x) (sizeof (x) / sizeof (x)[0])
the denominator is a pointer *if and only if* x happens to be an array
of pointers. The numerator is the size of the array as a whole; the
denominator is the size of a single element of the array. It's a
general-purpose macro for determining the length in elements of an array
*of any type*. (And of course it works only if the declaration of the
array object itself is visible and specifies the length.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-01-14 14:47 +0000 |
| Message-ID | <87o9z9n1ey.fsf@bsb.me.uk> |
| In reply to | #101737 |
Alla _ <modelling.data@gmail.com> writes:
> Please, read my explanation before answering, to show
> my mistake.
> Honestly, for some time now I was sure I have no problems
> with the statement sizeof(x) / sizeof(x[0]),
Small point: the brackets are in the wrong place. It is usual in macros
to put the parameter name in parentheses to prevent any possible
interaction with the surrounding symbols. The classic example being
#define square(x) x*x
which goes wrong when used like this:
square(a+1) => a+1*a+1
Similarly, one should put the whole expression in parentheses:
#define square(x) ((x)*(x))
Because of the high priority of the sizeof and [] operators, it is
likely that your expression will be fine, but the bets advice is to put
the parentheses in every time just to stop people wondering if it really
is OK or not:
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a)[0])
> usually used as
> the macro to compute the size of an array of strings. I was
> positive that I know how it works, and didn't doubt.
> Somehow today when I used this macro again I've experienced
> a confusion - how does it work, and what have I completely
> forgotten? Although shameful, I have decided to come here again
> for help on this matter.
>
> For example:
> char *array[] = {"abc", "defg", "hijklmop", NULL};
> The pointer points to an array that has 4 strings.
The array has four pointers. These pointers point to the start of
strings.
> sizeof(x) here will be sizeof(array) thus indicating
> the size in bytes of the whole array of strings,
It will be the size of the whole array of pointers: 4 times however many
bytes are in a char * on your machine (8 I think you once said).
> because 'array' here is used as the address of the
> first sub-element, which is 'a' (array is the same as
> array[0][0]);
No. 'array' in most contexts converts to a pointer to the first element
of that array -- i.e. it will have type char **. array is the same as
&array[0] (again in most contexts) and that is very much not the same as
array[0][0].
But remember, sizeof is one of the contexts where this conversion does
not occur. sizeof array gives the number of byte on the object called
array, even though in other contexts the expression array is converted
to a pointer.
> so sizeof(array) will give the number of bytes occupied
> by the whole array of strings, i.e. number
> of characters x 1 (which is the size of a char);
No, it gives the size of the the whole array of pointers because that's
what array is -- an array of pointers.
> the denominator sizeof(x[0]) gives the size of the
> first element of the array, i.e. the size of the first
> string, which is here "abc", so it it is 3 (3 characters,
> each 1 byte);
No. sizeof(array[0]) is the size of one of the pointers.
> and all other strings have different
> number of characters in them, and hence different
> number of bytes;
>
> how then sizeof(x) / sizeof(x[0]) gives a correct number
> of strings in the array (it actually does, I have tested it
> on different strings)? Please, show me my mistake.
It gives you the number of elements in the array so, yes, your tests
will work.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-14 07:17 -0800 |
| Message-ID | <3b0be4f0-5ef5-47fb-abb3-e6b4da367cd0@googlegroups.com> |
| In reply to | #101765 |
On Saturday, January 14, 2017 at 5:47:59 PM UTC+3, Ben Bacarisse wrote:
> Alla _ <modelling.data@gmail.com> writes:
>
> > Please, read my explanation before answering, to show
> > my mistake.
> > Honestly, for some time now I was sure I have no problems
> > with the statement sizeof(x) / sizeof(x[0]),
>
> Small point: the brackets are in the wrong place. It is usual in macros
> to put the parameter name in parentheses to prevent any possible
> interaction with the surrounding symbols. The classic example being
>
> #define square(x) x*x
>
> which goes wrong when used like this:
>
> square(a+1) => a+1*a+1
>
> Similarly, one should put the whole expression in parentheses:
>
> #define square(x) ((x)*(x))
>
> Because of the high priority of the sizeof and [] operators, it is
> likely that your expression will be fine, but the bets advice is to put
> the parentheses in every time just to stop people wondering if it really
> is OK or not:
>
> #define ARRAY_SIZE(a) (sizeof (a) / sizeof (a)[0])
>
> > usually used as
> > the macro to compute the size of an array of strings. I was
> > positive that I know how it works, and didn't doubt.
> > Somehow today when I used this macro again I've experienced
> > a confusion - how does it work, and what have I completely
> > forgotten? Although shameful, I have decided to come here again
> > for help on this matter.
> >
> > For example:
> > char *array[] = {"abc", "defg", "hijklmop", NULL};
> > The pointer points to an array that has 4 strings.
>
> The array has four pointers. These pointers point to the start of
> strings.
>
> > sizeof(x) here will be sizeof(array) thus indicating
> > the size in bytes of the whole array of strings,
>
> It will be the size of the whole array of pointers: 4 times however many
> bytes are in a char * on your machine (8 I think you once said).
>
> > because 'array' here is used as the address of the
> > first sub-element, which is 'a' (array is the same as
> > array[0][0]);
>
> No. 'array' in most contexts converts to a pointer to the first element
> of that array -- i.e. it will have type char **. array is the same as
> &array[0] (again in most contexts) and that is very much not the same as
> array[0][0].
>
> But remember, sizeof is one of the contexts where this conversion does
> not occur. sizeof array gives the number of byte on the object called
> array, even though in other contexts the expression array is converted
> to a pointer.
>
> > so sizeof(array) will give the number of bytes occupied
> > by the whole array of strings, i.e. number
> > of characters x 1 (which is the size of a char);
>
> No, it gives the size of the the whole array of pointers because that's
> what array is -- an array of pointers.
>
> > the denominator sizeof(x[0]) gives the size of the
> > first element of the array, i.e. the size of the first
> > string, which is here "abc", so it it is 3 (3 characters,
> > each 1 byte);
>
> No. sizeof(array[0]) is the size of one of the pointers.
>
> > and all other strings have different
> > number of characters in them, and hence different
> > number of bytes;
> >
> > how then sizeof(x) / sizeof(x[0]) gives a correct number
> > of strings in the array (it actually does, I have tested it
> > on different strings)? Please, show me my mistake.
>
> It gives you the number of elements in the array so, yes, your tests
> will work.
Thank you very much for this explanation. Of course! I see.
How could I forget this.
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@invalid.add> |
|---|---|
| Date | 2017-01-14 16:22 +0100 |
| Message-ID | <o5dfn9$6qt$1@gioia.aioe.org> |
| In reply to | #101737 |
On 1/14/2017 1:16 PM, Alla _ wrote:
> Hello!
>
> Please, read my explanation before answering, to show
> my mistake.
> Honestly, for some time now I was sure I have no problems
> with the statement sizeof(x) / sizeof(x[0]), ...
<snip>
> char *array[] = {"abc", "defg", "hijklmop", NULL};
> The pointer points to an array that has 4 strings.
<snip>
> so sizeof(array) will give the number of bytes occupied
> by the whole array of strings, i.e. number
> of characters x 1 (which is the size of a char);
>
> the denominator sizeof(x[0]) gives the size of the
> first element of the array, i.e. the size of the first
> string, which is here "abc", so it it is 3 (3 characters,
> each 1 byte); and all other strings have different
> number of characters in them, and hence different
> number of bytes;
Others have already explained that your array is an array of (4) char*,
so this is how it works - by the way the fact that your last element is
NULL requires that your array be an array of char*.
I only add here that from your explanation you probably confused this
array with what you could have declared as
char array[][9] = {"abc", "defg", "hijklmop", ""};
(note the final "" instead of NULL)
in this case you would have a 2-dimensional array of 4 rows where each
row (the strings "abc", "defg", "hijklmop", "") is 9 char long, and 36
bytes total size.
> how then sizeof(x) / sizeof(x[0]) gives a correct number
> of strings in the array (it actually does, I have tested it
> on different strings)? Please, show me my mistake.
>
> Thank you!
>
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2017-01-14 08:35 -0800 |
| Message-ID | <tmjk7cppga86gcc0022rvsrb8c84au0e0n@4ax.com> |
| In reply to | #101737 |
On Sat, 14 Jan 2017 04:16:30 -0800 (PST), Alla _
<modelling.data@gmail.com> wrote:
<snip>
>For example:
>char *array[] = {"abc", "defg", "hijklmop", NULL};
>The pointer points to an array that has 4 strings.
There is not "the pointer". There is only one named object. That
object is "the array" whose name is "array". The array consists of 4
elements. None of the elements is a string. All the elements are
pointers, pointers to char to be precise. Three of those elements are
in fact initialized to point to a string ( a different string for each
one). The fourth element is initialized to indicate it points
nowhere.
>sizeof(x) here will be sizeof(array) thus indicating
>the size in bytes of the whole array of strings,
There is no array of strings, only an array of pointers.
>because 'array' here is used as the address of the
>first sub-element, which is 'a' (array is the same as
>array[0][0]);
NO! The sizeof operator is an exception to the rule that an array
name is converted to a pointer to the first element.
In the non-exceptional case, the conversion would be equivalent to
&array[0] which would be the address of (not the address contained in)
the first pointer. The byte (not char) at that address would be
either the high order or low order byte of the address contained in
the pointer and most likely would not correspond to any printable
character. &array[0] would not point to the 'a' in "abc".
>so sizeof(array) will give the number of bytes occupied
>by the whole array of strings, i.e. number
>of characters x 1 (which is the size of a char);
It will give the number of bytes occupied by the array of pointers
which is completely independent of the length of the strings. Replace
"abc" in your initialization with
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" and
sizeof(array) yields the same value as yours. It will never count
characters.
>the denominator sizeof(x[0]) gives the size of the
>first element of the array, i.e. the size of the first
>string, which is here "abc", so it it is 3 (3 characters,
>each 1 byte); and all other strings have different
>number of characters in them, and hence different
>number of bytes;
No, it gives the size of the pointer.
>how then sizeof(x) / sizeof(x[0]) gives a correct number
>of strings in the array (it actually does, I have tested it
>on different strings)? Please, show me my mistake.
You do not have an array of strings. You have an array of pointers.
Except for the last, each of the pointers points to another array (of
char). The pointers are independent and in this case each points to a
different array. Those arrays have different sizes. The pointers
themselves are all the same size.
--
Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-15 22:53 -0800 |
| Message-ID | <d96856b2-263a-45a4-a0ab-41d7ed5c9655@googlegroups.com> |
| In reply to | #101779 |
On Saturday, January 14, 2017 at 7:35:56 PM UTC+3, Barry Schwarz wrote: > On Sat, 14 Jan 2017 04:16:30 -0800 (PST), Alla _ > <modelling.data@gmail.com> wrote: > > <snip> > >because 'array' here is used as the address of the > >first sub-element, which is 'a' (array is the same as > >array[0][0]); > > NO! The sizeof operator is an exception to the rule that an array > name is converted to a pointer to the first element. > > In the non-exceptional case, the conversion would be equivalent to > &array[0] which would be the address of (not the address contained in) > the first pointer. The byte (not char) at that address would be > either the high order or low order byte of the address contained in > the pointer and most likely would not correspond to any printable > character. &array[0] would not point to the 'a' in "abc". I am not sure I understood this correctly. You say that in normal, non-exceptional case, &array[0] doesn't guarantee to point to the first element in the first string? &array[0] does point to the first string, correct? Where else can it point to given the index? Could you, please, give an example with hexadecimal addresses, so I can see what can happen. Please. > <snip>
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-01-16 15:58 +0000 |
| Message-ID | <87eg03hu82.fsf@bsb.me.uk> |
| In reply to | #101924 |
Alla _ <modelling.data@gmail.com> writes:
> On Saturday, January 14, 2017 at 7:35:56 PM UTC+3, Barry Schwarz wrote:
>> On Sat, 14 Jan 2017 04:16:30 -0800 (PST), Alla _
>> <modelling.data@gmail.com> wrote:
>>
>> <snip>
>> >because 'array' here is used as the address of the
>> >first sub-element, which is 'a' (array is the same as
>> >array[0][0]);
>>
>> NO! The sizeof operator is an exception to the rule that an array
>> name is converted to a pointer to the first element.
I think the context here is
char *array[] = { "abc", "def", "..." };
>> In the non-exceptional case, the conversion would be equivalent to
>> &array[0] which would be the address of (not the address contained in)
>> the first pointer. The byte (not char) at that address would be
>> either the high order or low order byte of the address contained in
>> the pointer and most likely would not correspond to any printable
>> character. &array[0] would not point to the 'a' in "abc".
>
> I am not sure I understood this correctly. You say that in normal,
> non-exceptional case, &array[0] doesn't guarantee to point to the
> first element in the first string?
Yes, that's what he's saying. array is an array of pointers, so
array[0] is the first pointer and &array[0] is a pointer to that first
pointer.
> &array[0] does point to the first string,
> correct? Where else can it point to given the index?
It points to the first element of the array.
> Could you, please, give an example with hexadecimal addresses, so
> I can see what can happen. Please.
The compiler will make this structure:
0x100: 'a' 'b' 'c' 0
0x104: 'd' 'e' 'f' 0
0x108: '.' '.' '.' 0
0x10c: 0x100
0x110: 0x104
0x114: 0x108
The name `array` will be associated with the address 0x10c. The
following expressions have the values and types show:
expression value type
array 0x10c char **
array[0] 0x104 char *
array[0][0] 'a' char
&array 0x10c char (*)[4]
&array[0] 0x10c char **
&array[0][0] 0x104 char *
The types are important because a C pointer is an address with a
specific type.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-16 22:38 -0800 |
| Message-ID | <c1bc6814-89a0-4645-87e0-a94d55aae73c@googlegroups.com> |
| In reply to | #101970 |
On Monday, January 16, 2017 at 6:59:00 PM UTC+3, Ben Bacarisse wrote:
> Alla _ <modelling.data@gmail.com> writes:
>
> > On Saturday, January 14, 2017 at 7:35:56 PM UTC+3, Barry Schwarz wrote:
> >> On Sat, 14 Jan 2017 04:16:30 -0800 (PST), Alla _
> >> <modelling.data@gmail.com> wrote:
> >>
> >> <snip>
> >> >because 'array' here is used as the address of the
> >> >first sub-element, which is 'a' (array is the same as
> >> >array[0][0]);
> >>
> >> NO! The sizeof operator is an exception to the rule that an array
> >> name is converted to a pointer to the first element.
>
> I think the context here is
>
> char *array[] = { "abc", "def", "..." };
>
> >> In the non-exceptional case, the conversion would be equivalent to
> >> &array[0] which would be the address of (not the address contained in)
> >> the first pointer. The byte (not char) at that address would be
> >> either the high order or low order byte of the address contained in
> >> the pointer and most likely would not correspond to any printable
> >> character. &array[0] would not point to the 'a' in "abc".
> >
> > I am not sure I understood this correctly. You say that in normal,
> > non-exceptional case, &array[0] doesn't guarantee to point to the
> > first element in the first string?
>
> Yes, that's what he's saying. array is an array of pointers, so
> array[0] is the first pointer and &array[0] is a pointer to that first
> pointer.
>
> > &array[0] does point to the first string,
> > correct? Where else can it point to given the index?
>
> It points to the first element of the array.
>
> > Could you, please, give an example with hexadecimal addresses, so
> > I can see what can happen. Please.
>
> The compiler will make this structure:
>
> 0x100: 'a' 'b' 'c' 0
> 0x104: 'd' 'e' 'f' 0
> 0x108: '.' '.' '.' 0
> 0x10c: 0x100
> 0x110: 0x104
> 0x114: 0x108
>
> The name `array` will be associated with the address 0x10c. The
> following expressions have the values and types show:
>
> expression value type
> array 0x10c char **
> array[0] 0x104 char *
> array[0][0] 'a' char
> &array 0x10c char (*)[4]
> &array[0] 0x10c char **
> &array[0][0] 0x104 char *
>
> The types are important because a C pointer is an address with a
> specific type.
Thank you very much. Did you mean to write 0x100 in examples above?
0x104 is the address of the array[1], correct?
>
> --
> Ben.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-01-17 10:11 +0000 |
| Message-ID | <87o9z6gfnb.fsf@bsb.me.uk> |
| In reply to | #102021 |
Alla _ <modelling.data@gmail.com> writes:
> On Monday, January 16, 2017 at 6:59:00 PM UTC+3, Ben Bacarisse wrote:
<snip>
>> char *array[] = { "abc", "def", "..." };
<snip>
Corrected:
>> The compiler will make this structure:
>>
>> 0x100: 'a' 'b' 'c' 0
>> 0x104: 'd' 'e' 'f' 0
>> 0x108: '.' '.' '.' 0
>> 0x10c: 0x100
>> 0x110: 0x104
>> 0x114: 0x108
>>
>> The name `array` will be associated with the address 0x10c. The
>> following expressions have the values and types shown:
>>
>> expression value type
>> array 0x10c char **
>> array[0] 0x100 char *
>> array[0][0] 'a' char
>> &array 0x10c char (*)[4]
>> &array[0] 0x10c char **
>> &array[0][0] 0x100 char *
>>
>> The types are important because a C pointer is an address with a
>> specific type.
>
> Thank you very much. Did you mean to write 0x100 in examples above?
> 0x104 is the address of the array[1], correct?
Yes. I was sure there would be some error in it, but I'm glad it did
not throw you off course. (I've edited my quote.)
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-01-14 11:43 -0500 |
| Message-ID | <o5dkc2$gf1$1@dont-email.me> |
| In reply to | #101737 |
On 01/14/2017 07:16 AM, Alla _ wrote:
> Hello!
>
> Please, read my explanation before answering, to show
> my mistake.
> Honestly, for some time now I was sure I have no problems
> with the statement sizeof(x) / sizeof(x[0]), usually used as
> the macro to compute the size of an array of strings. I was
> positive that I know how it works, and didn't doubt.
> Somehow today when I used this macro again I've experienced
> a confusion - how does it work, and what have I completely
> forgotten? Although shameful, I have decided to come here again
> for help on this matter.
>
> For example:
> char *array[] = {"abc", "defg", "hijklmop", NULL};
> The pointer points to an array that has 4 strings.
> sizeof(x) here will be sizeof(array) thus indicating
> the size in bytes of the whole array of strings,
> because 'array' here is used as the address of the
> first sub-element, which is 'a' (array is the same as
> array[0][0]);
>
> so sizeof(array) will give the number of bytes occupied
> by the whole array of strings, i.e. number
> of characters x 1 (which is the size of a char);
>
> the denominator sizeof(x[0]) gives the size of the
> first element of the array, i.e. the size of the first
> string, which is here "abc", so it it is 3 (3 characters,
> each 1 byte); and all other strings have different
> number of characters in them, and hence different
> number of bytes;
>
> how then sizeof(x) / sizeof(x[0]) gives a correct number
> of strings in the array (it actually does, I have tested it
> on different strings)? Please, show me my mistake.
Other people had already answered before I could find the time to
respond. However, part of what I wanted to say has not yet been
explicitly said by anyone else:
In C, a string is not a data type, it is a data format. You cannot
declare a string. There's two things that people often think of then
they think they're declaring a string:
char char_array[] = "Hello ";
char *char_ptr = "world!\n";
"Hello " and "world!\n" are string literals. They cause the creation of
an unnamed char array of sufficient length to be initialized with the
specified characters, including a terminating null character. As a
result, those arrays do contain strings. In most contexts, a string
literal is automatically converted into a pointer to the first element
of that array. The initialization of an array of character type (such as
char_array above) is NOT one of those contexts. What the standard
actually says about such things makes those definitions equivalent (if
char_array has automatic storage duration) to the following code:
char __unnamed1[] = {'H', 'e', 'l', 'l', 'o', ' ', '\0'};
char char_array[sizeof __unnamed1];
memcpy(char_array, _unnamed1, sizeof __unnamed1);
char __unnamed2[] = {'W', 'o', 'r', 'l', 'd', '!', '\n', '\0'};
char *char_ptr = unnamed2;
The equivalence breaks down for arrays with file scope, which provides
no location for the memcpy() call, or for local arrays with static
storage duration, where the memcpy() call should only occur once, before
the start of the program. As described by the standard, the copy still
occurs in those cases, there's just no strictly conforming C code that
has exactly equivalent behavior.
Note that there is no way for a strictly conforming program to determine
whether or not __unnamed1 even exists. As a result, if char_array has
static storage duration, removing __unnamed1 and just initializing
char_array directly is a common optimization:
char char_array[] = {'H', 'e', 'l', 'l', 'o', ' ', '\0'};
So, char_array is an array of char which can (but doesn't have to)
contain a string, while char_ptr is a pointer to char which can (but
doesn't have to) point at a string. Neither of those is a string itself.
You can create an array of char that does not contain a string, and a
char * pointer which points at something that is not a string, using the
following code:
char hello[6] = "Hello ";
char *greeting = hello;
That first declaration has the same net result as
char hello[6] = {'H', 'e', 'l', 'l', 'o', ' '};
which does NOT contain a terminating null character, and is therefore
not a C string. Code that is intended to read strings will start
searching for a null character, and when it doesn't find any, it will
keep searching past the end of the string. As far as the standard is
concerned, such code has undefined behavior. On real-world
implementations, the search is likely to find a terminating null
character somewhere, sooner or later, unless it first wanders into
memory that it has no permission to read.
Now let's move up to two dimensions. Your "array" is an array of char *
pointers, initialized to point at the strings contained in the unnamed
arrays corresponding to those string literals. "sizeof array" gives the
size of those pointers, but not of the strings that they point at. The
following declaration, on the other hand:
char array2d[][9] = {"abc", "defg", "hijklmop", ""};
Is equivalent to
char array2d[][9] = {
{'a', 'b', 'c', '\0'},
{'d', 'e', 'f', 'g', '\0'},
{'h', 'i', 'j', 'k', 'l', 'm', 'o', 'p', '\0'},
{'\0'}
};
Note that with this definition, "sizeof array2d" has the value of 36,
because it's got four elements, each of which contains 9 chars. This
also is NOT the total length of the strings.
char segmented_string[] = "abc\0defg\0hijklmop\0";
The array segmented_string contains all four of the strings that the
elements of your "array" pointed at, starting at segmented_string,
segmented_string+4, segmented_string+9, and segmented_string+18,
respectively. The expression "sizeof segmented_string" has a value of
19, which is the total length of those strings, including their
terminating null characters. That array also contains 15 other strings,
such as "bc", which starts at segmented_string+1, and "p", which starts
at segmented_string+16.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-14 16:01 -0800 |
| Message-ID | <lnziitgpib.fsf@kst-u.example.com> |
| In reply to | #101780 |
James Kuyper <jameskuyper@verizon.net> writes:
[...]
> char segmented_string[] = "abc\0defg\0hijklmop\0";
>
> The array segmented_string contains all four of the strings that the
> elements of your "array" pointed at, starting at segmented_string,
> segmented_string+4, segmented_string+9, and segmented_string+18,
> respectively. The expression "sizeof segmented_string" has a value of
> 19, which is the total length of those strings, including their
> terminating null characters. That array also contains 15 other strings,
> such as "bc", which starts at segmented_string+1, and "p", which starts
> at segmented_string+16.
True, but I'd place a different emphasis.
The "length" of a string by definition excludes the terminating null
character (which is part of the string but does not contribute to its
"length").
`sizeof segmented_string` does happen to be "the total length of those
strings, including their terminating null characters", but it's simpler
and more correct to say that it's the size of the array object,
regardless of its contents. For example, if you had written:
char segmented_string[42] = "abc\0defg\0hijklmop\0";
then `sizeof segmented_string` would be 42.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-16 01:36 -0800 |
| Message-ID | <e3c1e893-77f1-41b9-92c7-452e02c193a1@googlegroups.com> |
| In reply to | #101780 |
On Saturday, January 14, 2017 at 7:43:21 PM UTC+3, James Kuyper wrote:
> On 01/14/2017 07:16 AM, Alla _ wrote:
> > Hello!
> >
> > Please, read my explanation before answering, to show
> > my mistake.
> > Honestly, for some time now I was sure I have no problems
> > with the statement sizeof(x) / sizeof(x[0]), usually used as
> > the macro to compute the size of an array of strings. I was
> > positive that I know how it works, and didn't doubt.
> > Somehow today when I used this macro again I've experienced
> > a confusion - how does it work, and what have I completely
> > forgotten? Although shameful, I have decided to come here again
> > for help on this matter.
> >
> > For example:
> > char *array[] = {"abc", "defg", "hijklmop", NULL};
> > The pointer points to an array that has 4 strings.
> > sizeof(x) here will be sizeof(array) thus indicating
> > the size in bytes of the whole array of strings,
> > because 'array' here is used as the address of the
> > first sub-element, which is 'a' (array is the same as
> > array[0][0]);
> >
> > so sizeof(array) will give the number of bytes occupied
> > by the whole array of strings, i.e. number
> > of characters x 1 (which is the size of a char);
> >
> > the denominator sizeof(x[0]) gives the size of the
> > first element of the array, i.e. the size of the first
> > string, which is here "abc", so it it is 3 (3 characters,
> > each 1 byte); and all other strings have different
> > number of characters in them, and hence different
> > number of bytes;
> >
> > how then sizeof(x) / sizeof(x[0]) gives a correct number
> > of strings in the array (it actually does, I have tested it
> > on different strings)? Please, show me my mistake.
>
> Other people had already answered before I could find the time to
> respond. However, part of what I wanted to say has not yet been
> explicitly said by anyone else:
>
> In C, a string is not a data type, it is a data format. You cannot
> declare a string. There's two things that people often think of then
> they think they're declaring a string:
>
> char char_array[] = "Hello ";
> char *char_ptr = "world!\n";
>
> "Hello " and "world!\n" are string literals. They cause the creation of
> an unnamed char array of sufficient length to be initialized with the
> specified characters, including a terminating null character. As a
> result, those arrays do contain strings. In most contexts, a string
> literal is automatically converted into a pointer to the first element
> of that array. The initialization of an array of character type (such as
> char_array above) is NOT one of those contexts. What the standard
> actually says about such things makes those definitions equivalent (if
> char_array has automatic storage duration) to the following code:
>
> char __unnamed1[] = {'H', 'e', 'l', 'l', 'o', ' ', '\0'};
> char char_array[sizeof __unnamed1];
> memcpy(char_array, _unnamed1, sizeof __unnamed1);
>
> char __unnamed2[] = {'W', 'o', 'r', 'l', 'd', '!', '\n', '\0'};
> char *char_ptr = unnamed2;
>
> The equivalence breaks down for arrays with file scope, which provides
> no location for the memcpy() call, or for local arrays with static
> storage duration, where the memcpy() call should only occur once, before
> the start of the program. As described by the standard, the copy still
> occurs in those cases, there's just no strictly conforming C code that
> has exactly equivalent behavior.
> Note that there is no way for a strictly conforming program to determine
> whether or not __unnamed1 even exists. As a result, if char_array has
> static storage duration, removing __unnamed1 and just initializing
> char_array directly is a common optimization:
>
> char char_array[] = {'H', 'e', 'l', 'l', 'o', ' ', '\0'};
>
> So, char_array is an array of char which can (but doesn't have to)
> contain a string, while char_ptr is a pointer to char which can (but
> doesn't have to) point at a string. Neither of those is a string itself.
>
Thank you for this interesting explanation. I would like to ask for a bit
clarification, if I may:
char __unnamed1[] = {'H', 'e', 'l', 'l', 'o', ' ', '\0'};
char char_array[sizeof __unnamed1];
char char_array[] = {'H', 'e', 'l', 'l', 'o', ' ', '\0'};
Do I understand correctly that you can say the same thing about
char _unnamed1[]? I don't see how it differs from char _char_array[],
when same literals are assigned to them, like in this case {'H', 'e', 'l', 'l', 'o', ' ', '\0'}?
> You can create an array of char that does not contain a string, and a
> char * pointer which points at something that is not a string, using the
> following code:
>
> char hello[6] = "Hello ";
> char *greeting = hello;
>
> That first declaration has the same net result as
>
> char hello[6] = {'H', 'e', 'l', 'l', 'o', ' '};
>
> which does NOT contain a terminating null character, and is therefore
> not a C string. Code that is intended to read strings will start
> searching for a null character, and when it doesn't find any, it will
> keep searching past the end of the string. As far as the standard is
> concerned, such code has undefined behavior. On real-world
> implementations, the search is likely to find a terminating null
> character somewhere, sooner or later, unless it first wanders into
> memory that it has no permission to read.
>
> Now let's move up to two dimensions. Your "array" is an array of char *
> pointers, initialized to point at the strings contained in the unnamed
> arrays corresponding to those string literals. "sizeof array" gives the
> size of those pointers, but not of the strings that they point at. The
> following declaration, on the other hand:
>
> char array2d[][9] = {"abc", "defg", "hijklmop", ""};
>
> Is equivalent to
>
> char array2d[][9] = {
> {'a', 'b', 'c', '\0'},
> {'d', 'e', 'f', 'g', '\0'},
> {'h', 'i', 'j', 'k', 'l', 'm', 'o', 'p', '\0'},
> {'\0'}
> };
>
> Note that with this definition, "sizeof array2d" has the value of 36,
> because it's got four elements, each of which contains 9 chars. This
> also is NOT the total length of the strings.
>
> char segmented_string[] = "abc\0defg\0hijklmop\0";
>
> The array segmented_string contains all four of the strings that the
> elements of your "array" pointed at, starting at segmented_string,
> segmented_string+4, segmented_string+9, and segmented_string+18,
> respectively. The expression "sizeof segmented_string" has a value of
> 19, which is the total length of those strings, including their
> terminating null characters. That array also contains 15 other strings,
> such as "bc", which starts at segmented_string+1, and "p", which starts
> at segmented_string+16.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web