different behavior of "sizeof()"

Started by
9 comments, last by the_edd 11 years, 9 months ago
Hi,

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


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

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


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!
"lots of shoulddas, coulddas, woulddas in the air, thinking about things they shouldda couldda wouldda donne, however all those shoulddas coulddas woulddas ran away when they saw the little did to come"
Advertisement
This is how sizeof is supposed to work. If you use sizeof on an array you get the size of the array. If you use sizeof on a pointer you get the size of the pointer. It doesn't matter what the pointer points to; if you ask for the size of a pointer, you'll get the size of the pointer.
@SiCrane: If you passed an array instead of a pointer, would it return 4 or 30?

int checkSize( char []str )
{
return sizeof( str );
}
I think in that case you would still get '4' as char[] str has no size and is thus treated as a pointer.
Still just the size of a pointer there. Note that you got the [] in the wrong place though. In C++ it comes after the variable name.

The bit of knowledge that you are lacking which would enable you to work out why it is like this, and answer the question for yourself, is that sizeof gets replaced with a single number at compile time. That clearly demonstrates how neither checkSize function case could result in returning the size of the array whose pointer was passed in, because there is no way for this function to return anything but the same value every time.
Then if you think about how it is used in main (which incidentally must return int, not void) The array that you are using it on can only be of one size, so you get that array's size no problem.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Thanks!

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

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

Thanks to all of you!
"lots of shoulddas, coulddas, woulddas in the air, thinking about things they shouldda couldda wouldda donne, however all those shoulddas coulddas woulddas ran away when they saw the little did to come"

@SiCrane: If you passed an array instead of a pointer, would it return 4 or 30?

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 where the size of the array is specified. So even if you made the argument a char[30] you'd still get a pointer size back.
A useful trick is passing a reference to an array to prevent decaying to a pointer.


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


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

template<typename T, std::size_t N>
std::size_t array_length(const T (&array)[N])
{
return N;
}
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).

This topic is closed to new replies.

Advertisement