Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #101748

Re: sizeof(x) / sizeof(x[0])

From jt@toerring.de (Jens Thoms Toerring)
Newsgroups comp.lang.c
Subject Re: sizeof(x) / sizeof(x[0])
Date 2017-01-14 13:13 +0000
Organization Freie Universitaet Berlin
Message-ID <edumfuF7genU1@mid.uni-berlin.de> (permalink)
References <1420cd8f-e5cb-4a8f-93e6-d80a8b050650@googlegroups.com>

Show all headers | View raw


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

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

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

csiph-web