Sign in to follow this  
jakovo

different behavior of "sizeof()"

Recommended Posts

Hi,

I have just come to notice something strange in the behavior of sizeof() function, if I write:

[CODE]
int checkSize( char *str )
{
return sizeof( str );
}

void main()
{
char text[30];
int size = sizeof( text ); // size = 30
int size2= checkSize( text ); // size2 = 4
}
[/CODE]

size gets the value of the length of the array, but size2 gets 4 (the size of the sole pointer).

does anyone know why?...

is this the standard way of C++ to behave?... or is it maybe compiler thing?

Thanks!

Share this post


Link to post
Share on other sites
Thanks!

yes, I tried also using [b]char str[][/b] as argument too, but it returned the same value.

I think [b]iMalc[/b]'s answer really pointed out how C++ decides to return the value when using [b]sizeof()[/b].

Thanks to all of you!

Share this post


Link to post
Share on other sites
[quote name='Servant of the Lord' timestamp='1342908936' post='4961779']
@SiCrane: If you passed an array instead of a pointer, would it return 4 or 30?
[/quote]
In C++, a function argument with a type array of T is automatically transformed into a type of pointer to T. This includes function arguments [i]where the size of the array is specified[/i]. So even if you made the argument a char[30] you'd still get a pointer size back.

Share this post


Link to post
Share on other sites
A useful trick is passing a reference to an array to prevent decaying to a pointer.

[code]
template<typename T, std::size_t N>
std::size_t array_length(const T (&array)[N])
{
return sizeof array / sizeof *array;
}
[/code]

Of course, if you pass it a string literal, you'll get an length that includes the '\0'.

Share this post


Link to post
Share on other sites
And these will work only on static arrays. As the others said, sizeof gets replaced with a number at compile time. That is why all the WIN_STRUCT_NAME.cbSize vooodo works, otherwize this mechanism would be pretty much pointless.
I would advice you to either pass the size (with an additional argument, as C functions do), or, even better, use the built-in array (in c++11) or vector for dynamic arrays. You get bound checking for free (I hate out-of-index).

Share this post


Link to post
Share on other sites
[quote name='rip-off' timestamp='1342951961' post='4961904']
Alternative implementation:
[code]
template<typename T, std::size_t N>
std::size_t array_length(const T (&array)[N])
{
return N;
}
[/code]
[/quote]

Face-palming somewhat right now.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this