Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > sizeof()'s strange behviour

Reply
Thread Tools

sizeof()'s strange behviour

 
 
Richard Bos
Guest
Posts: n/a
 
      04-08-2008
arnuld <(E-Mail Removed)> wrote:

> sizeof() operator gives 2 different types of size outputs :\ but I do not
> understand why:


You need to read this <http://c-faq.com/aryptr/index.html> section of
the FAQ; in particular question 6.4, but the rest will be useful, too.

Richard
 
Reply With Quote
 
 
 
 
Philip Potter
Guest
Posts: n/a
 
      04-08-2008
arnuld wrote:
> sizeof() operator gives 2 different types of size outputs :\ but I do not
> understand why:
>
> #include <stdio.h>
> #include <stdlib.h>
>
>
> int my_size( char [] );
>
>
> int main()
> {
> char s[] = "Saurabh Nirkhey";
>
> printf("sizeof(%s): %d\n", s, sizeof(s));
> printf("sizeof(%s): %d\n", s, my_size(s));
>
>
> return 0;
> }
>
> int my_size( char s[] )
> {
> return sizeof(s);
> }


In C, arrays cannot be used as function parameters. While it looks like
my_size() takes a char [], C rewrites the declaration so that it
actually takes a char *. The value passed to my_size() is a pointer to
the first element of s (if it helps, you can think of it as &s[0]). The
s within my_size is therefore a char *, and sizeof(s) tells you the size
of a char *.

Usually strlen() is the correct tool when dealing with strings.

See also FAQ question 6.4 (the clc FAQ is at http://c-faq.com/), and the
whole of section 6 is probably useful.

pgp@bullfinch:~/tmp$ cat str.c
#include <stdio.h>
#include <string.h>
int main(void) {
char str1[10] = "String";
char str2[100] = "String";
printf("str1 and str2 are %s\n",
strcmp(str1,str2) == 0 ? "equal" : "not equal");
printf("strlen(str1) == %d, strlen(str2) == %d\n",
strlen(str1),strlen(str2));
printf("sizeof str1 == %d, sizeof str2 == %d\n",
sizeof str1, sizeof str2);
return 0;
}
pgp@bullfinch:~/tmp$ gcc -ansi -pedantic -ostr str.c
pgp@bullfinch:~/tmp$ ./str
str1 and str2 are equal
strlen(str1) == 6, strlen(str2) == 6
sizeof str1 == 10, sizeof str2 == 100
pgp@bullfinch:~/tmp$

The above shows that sizeof and strlen are measuring different things.
sizeof tells you the size of a type (in this case two array types,
char[10] and char[100]), while strlen() tells you the length of a string
(which may not fill the whole array).
 
Reply With Quote
 
 
 
 
arnuld
Guest
Posts: n/a
 
      04-08-2008
sizeof() operator gives 2 different types of size outputs :\ but I do not
understand why:


#include <stdio.h>
#include <stdlib.h>


int my_size( char [] );


int main()
{
char s[] = "Saurabh Nirkhey";

printf("sizeof(%s): %d\n", s, sizeof(s));
printf("sizeof(%s): %d\n", s, my_size(s));


return 0;
}



int my_size( char s[] )
{
return sizeof(s);
}


============ OUTPUT =============
/home/arnuld/programs/C $ gcc -ansi -pedantic -Wall -Wextra 5-4.c
/home/arnuld/programs/C $ ./a.out
sizeof(Saurabh Nirkhey): 16
sizeof(Saurabh Nirkhey): 4
/home/arnuld/programs/C $


--http://lispmachine.wordpress.com/

Please remove capital 'V's when you reply to me via e-mail.

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      04-08-2008
Richard Heathfield <(E-Mail Removed)> writes:
> arnuld said:

[...]
>> printf("sizeof(%s): %d\n", s, sizeof(s));

>
> ...so we'd expect this to print 16 in place of the second % format
> specifier. Note that your printf is misleading. It will print:
>
> sizeof(Saurabh Nirkhey): 16
>
> but in fact it's sizeof s that is 16.

[...]

Furthermore, "%d" causes printf to expect an int argument, but
sizeof(s) is of type size_t. It's likely to happen to work on systems
where int and size_t are the same size, but the right way is (with a
couple of other tweaks):

printf("sizeof s: %d\n", (int)sizeof s);

--
Keith Thompson (The_Other_Keith) <(E-Mail Removed)>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Philip Potter
Guest
Posts: n/a
 
      04-08-2008
Keith Thompson wrote:
> Richard Heathfield <(E-Mail Removed)> writes:
>> arnuld said:

> [...]
>>> printf("sizeof(%s): %d\n", s, sizeof(s));

>> ...so we'd expect this to print 16 in place of the second % format
>> specifier. Note that your printf is misleading. It will print:
>>
>> sizeof(Saurabh Nirkhey): 16
>>
>> but in fact it's sizeof s that is 16.

> [...]
>
> Furthermore, "%d" causes printf to expect an int argument, but
> sizeof(s) is of type size_t. It's likely to happen to work on systems
> where int and size_t are the same size, but the right way is (with a
> couple of other tweaks):
>
> printf("sizeof s: %d\n", (int)sizeof s);
>

Richard mentioned this already in his post.

I'd add that C99 provides the 'z' format modifier for size_t values:

printf("sizeof s: %zd\n", sizeof s);

....although if your code isn't C99 for other reasons, this is hardly a
great reason to break C90 compatibility.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      04-08-2008
Philip Potter <(E-Mail Removed)> writes:
> Keith Thompson wrote:
>> Richard Heathfield <(E-Mail Removed)> writes:
>>> arnuld said:

>> [...]
>>>> printf("sizeof(%s): %d\n", s, sizeof(s));
>>> ...so we'd expect this to print 16 in place of the second % format
>>> specifier. Note that your printf is misleading. It will print:
>>>
>>> sizeof(Saurabh Nirkhey): 16
>>>
>>> but in fact it's sizeof s that is 16.

>> [...]
>>
>> Furthermore, "%d" causes printf to expect an int argument, but
>> sizeof(s) is of type size_t. It's likely to happen to work on systems
>> where int and size_t are the same size, but the right way is (with a
>> couple of other tweaks):
>>
>> printf("sizeof s: %d\n", (int)sizeof s);
>>

> Richard mentioned this already in his post.


Did he? I expected him to do so, and I was surprised when I didn't
see it, and surprised again when I didn't see it when I re-read his
article just now. He did mention that size_t yields a size_t rather
than an int, but in the context of returning the result from the OP's
my_size() function, not in the context of passing the result to
printf.

[...]

--
Keith Thompson (The_Other_Keith) <(E-Mail Removed)>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
arnuld
Guest
Posts: n/a
 
      04-09-2008
> On Tue, 08 Apr 2008 11:16:40 +0000, Richard Heathfield wrote:

> Anyway, bottom line is: what you've discovered is that you can't pass
> arrays to functions. You can fake it, but you can't actually pass the
> array itself. If you try to take an array's value (e.g. by passing it to a
> function or adding it to an integer value), what you actually get is a
> pointer to the array's first element.


> .... {SNIP}...


> So evaluating the name of an array gives a pointer to the first element,
> QED.



okay, I have written this. So now I know about both sizeof() and that
arrays can not be passed to functions :

/* A program to understand the output of sizeof operator
*
*/



#include <stdio.h>
#include <stdlib.h>


int main()
{
int arr_char, arr_int, arr_LD;
char ac[] = "abc";
int ai[] = { 1, 2, 3};
long double ald[] = { 1.3, 78659.90098, 0.0001 };

/* casting to int because sizeof yields a size_t value */
arr_char = (int) sizeof( ac );
arr_int = (int) sizeof( ai );
arr_LD = (int) sizeof( ald );

printf("Size of different types of Arrays in BYTES: \n");
printf("\n%d\n", arr_char);
printf("%d\n", arr_int);
printf("%d\n", arr_LD);

arr_char = ( (int) sizeof(ac) / sizeof(char) ) - 1;
arr_int = ( (int) sizeof(ai) / sizeof(int) );
arr_LD = ( (int) sizeof(ald) / sizeof(long double) );
printf("\nSize of Arrays themselves, number of elements they contain: \n");
printf("\n%d\n", arr_char);
printf("%d\n", arr_int);
printf("%d\n", arr_LD);


return EXIT_SUCCESS;
}

========= OUTPUT ==============
/home/arnuld/programs/C $ gcc -ansi -pedantic -Wall -Wextra test.c
/home/arnuld/programs/C $ ./a.out
Size of different types of Arrays in BYTES:

4
12
36

Size of Arrays themselves, number of elements they contain:

3
3
3
/home/arnuld/programs/C $




-- http://lispmachine.wordpress.com/

Please remove capital 'V's when you reply to me via e-mail.

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      04-09-2008
arnuld <(E-Mail Removed)> writes:
[...]
> okay, I have written this. So now I know about both sizeof() and that
> arrays can not be passed to functions :
>
> /* A program to understand the output of sizeof operator
> *
> */
>


Overall, it's not a bad demonstration, but I have few comments.

>
> #include <stdio.h>
> #include <stdlib.h>
>
>
> int main()


Ok, but "int main(void)" is preferred.

> {
> int arr_char, arr_int, arr_LD;
> char ac[] = "abc";
> int ai[] = { 1, 2, 3};
> long double ald[] = { 1.3, 78659.90098, 0.0001 };
>
> /* casting to int because sizeof yields a size_t value */
> arr_char = (int) sizeof( ac );
> arr_int = (int) sizeof( ai );
> arr_LD = (int) sizeof( ald );


The casts are unnecessary. Both size_t and int are integral types;
one will be implicitly converted to the other by the assignment.

The parentheses on the sizeof operators are also unnecessary; they're
needed only when the argument is a type name, or when you need them to
specify grouping. Thus:

arr_char = sizeof ac;
arr_int = sizeof ai;
arr_LD = sizeof ald;

Better yet, since these three variables hold the result of sizeof,
declare them as size_t (or maybe not; see below).

> printf("Size of different types of Arrays in BYTES: \n");
> printf("\n%d\n", arr_char);
> printf("%d\n", arr_int);
> printf("%d\n", arr_LD);


Good. Note that if you followed my advice above and declared these as
size_t, you'd need to cast them to int for printf. It's usually best
to declare something of the appropriate type for what it needs to
hold, but in this case using int does simplify the code. There are
always tradeoffs.

> arr_char = ( (int) sizeof(ac) / sizeof(char) ) - 1;
> arr_int = ( (int) sizeof(ai) / sizeof(int) );
> arr_LD = ( (int) sizeof(ald) / sizeof(long double) );


More unnecessary casts and excessive parentheses. And the "- 1" for
arr_char presumably is intended to allow for the trailing '\0' on the
string -- but that '\0' is just as much part of the array as the 'a',
'b', and 'c' are. Your array ac is 4 elements long, not 3.

Note that sizeof(char) is 1 by definition.

And here's a good idiom for computing the length of an array:

arr_char = sizeof ac / sizeof ac[0];
arr_int = sizeof ai / sizeof ai[0];
arr_LD = sizeof ald / sizeof ald[0];

Of course, when using this idiom you have to make sure that the name
(ac, ai, or ald) is actually the name of an array object, not of, say,
a function parameter that's really a pointer.

> printf("\nSize of Arrays themselves, number of elements they contain: \n");
> printf("\n%d\n", arr_char);
> printf("%d\n", arr_int);
> printf("%d\n", arr_LD);
>
>
> return EXIT_SUCCESS;
> }


Good. (Note that "return 0;" is equally valid.)

[snip]

--
Keith Thompson (The_Other_Keith) <(E-Mail Removed)>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
AVG Email Scanner activating at strange times with strange IP addresses dennispublic@hotmail.com Computer Support 1 08-26-2006 04:27 AM
Need to emulate browser behviour from a java class shacoof@gmail.com Java 1 10-26-2005 10:18 AM
20D flash behviour dajaxon Digital Photography 11 12-14-2004 11:31 PM
Strange taskbar behaviour (notification area) Falcon Wireless Networking 0 08-17-2004 09:03 AM
Question About Strange 'C' Code Syntax ( Well strange to me anyway ) Harvey Twyman C Programming 8 10-25-2003 05:54 AM



Advertisments