Link to home
Start Free TrialLog in
Avatar of suoju1
suoju1

asked on

sizeof operator question?

we have the following code with output, why the function getSize( float *ptr ) return 4 and not 80??

1    /* Fig. 7.16: fig07_16.c//
2       Sizeof operator when used on an array name
3       returns the number of bytes in the array. */
4    #include <stdio.h>
5    
6    size_t getSize( float *ptr ); /* prototype */
7    
8    int main()
9    {
10      float array[ 20 ]; /* create array */
11  
12      printf( "The number of bytes in the array is %d"            
13              "\nThe number of bytes returned by getSize is %d\n",
14              sizeof( array ), getSize( array ) );                
15  
16      return 0; /* indicates successful termination */
17  
18   } /* end main */
19  
20   /* return size of ptr */
21   size_t getSize( float *ptr )
22   {
23      return sizeof( ptr );
24  
25      } /* end function getSize */26      


The number of bytes in the array is 80
The number of bytes returned by getSize is 4???

Avatar of Axter
Axter
Flag of United States of America image

Because sizeof returns the size of the variable, and not the size of the array.

4 bytes is the size of a pointer.
ptr is a pointer to float. That is generally a 32bit (4 byte) datatype.

If you want it to return the size of the array, you can't do it that way. You'll have to either add a sentinel at the end of the array, or keep the size stored somewhere.
You can not use a pointer to determine the size of an array.

If you want to know the size of the array, you need to store that information.
Avatar of suoju1
suoju1

ASKER

but how come the sizeof( array ) do?
>>but how come the sizeof( array ) do?

because variable array is not a pointer, where as variable ptr is a pointer.
Avatar of suoju1

ASKER

where to get help about description of the method of sizeof( ) ,
i check online libary about c like :

http://www.utas.edu.au/infosys/info/documentation/C/CStdLib.html
http://www.csse.uwa.edu.au/programming/ansic-library.html

and i could not find it.
Have a look at the standard - a draft copy of the C99 standard is available here:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
>> where to get help about description of the method of sizeof( ) ,

sizeof returns the size in bytes of the argument passed to it. When you pass a pointer, it returns the size of the pointer, NOT the data it points to.

        char *ptr;
        sizeof(ptr);   /* <--- 4 */

When you pass an array, it returns the size of the array :

        char arr[10];
        sizeof(arr);   /* <--- 10 */
>>where to get help about description of the method of sizeof( ) ,

Just a quickie - remember that sizeof is not a function or method, it is an operator.  It 'evaluates' [to some value obviously].
>> Just a quickie - remember that sizeof is not a function or method, it is an operator.  It 'evaluates' [to some value obviously].
You should also note it is evaluated at compile time and NOT at runtime.

>> because variable array is not a pointer, where as variable ptr is a pointer.
When you pass an array to a function that takes a pointer of the same type it automatically decomposes to that pointer type.

A series of good articles on this subject by Siavosh Kasravi: -
http://www.cplusplus.com/articles/Arrptrexc.html
http://www.cplusplus.com/articles/Arrptr.html
http://www.cplusplus.com/articles/siavoshkc1.html
>>You should also note it is evaluated at compile time and NOT at runtime.

That's not strictly true with C99 now - the *only* time sizeof now evaluates at runtime is with C99s variable sized arrays.
>> sizeof now evaluates at runtime is with C99s variable sized arrays.
Yes, for that exception you are right -- thanks for clarifying that peetm.
>>That's not strictly true with C99 now - the *only* time sizeof now evaluates at runtime is with C99s variable sized arrays.

FYI:
This question has been posted in both C and C++ topic areas.
In C++ sizeof is always evaluated at compile time.
Well, there is a simple enough C++ test to prove it is a compile time value. A template value type is immutable and as such it MUST be a compile time constant (ie. the value is known and constant as compile time). This being the case, if sizeof wan't evaluated at compile time it couldn't be used as a template parameter -- it can. Conversely, a non-const or const that is not locally initialized with a known value at compile time (such as a const function parameter) cannot be passed as a template parameter as it's value cannot be known until runtime.
// A small template that can only be instantiated with a valid compile time constant.
template <size_t N>
struct STATIC_ASSERT_COMPILE_TIME_CONST{};
 
 
// This will build as sizeof is a compile time constant
int const x = 9;
STATIC_ASSERT_COMPILE_TIME_CONST<sizeof(x)>;
 
// This will also build as the value of x is a constant with a known value at compile time
int const x = 9;
STATIC_ASSERT_COMPILE_TIME_CONST<x>;
 
	
// This will fail to build as x is not a constant with a known value at compile time
int x = 9;
STATIC_ASSERT_COMPILE_TIME_CONST<x>;

Open in new window

Avatar of suoju1

ASKER

if i want to get getSize method return the size of array which is 80 bits, how the following function have to be changed??

21   size_t getSize( float *ptr )
22   {
23      return sizeof( ptr );
24  
25      } /* end function getSize */26      
It is NOT possible to do it using just a pointer. Using a normal runtime function you'd have to tell the function the size of the array you want to pass in in the argument list definition, which kind of defeats the point of what you re looking to do. The best you can do is make it a template function (below); however, why don't you just use sizeof directly on the array? What do you hope to achieve by doing this via an indirection function call?
// This will get the size of any type
template <typename T>
size_t GetSize(T const & t)
{
	return sizeof(t);
}
 
int main()
{
	float x[10] = {0};
	size_t size = GetSize(x);
	// size == 40
	return 0;
}

Open in new window

Avatar of suoju1

ASKER

template is used for C++,  so one way to switch to C++

another way is to stick with C and  pass size of the array with the pointer
so the prototype is like the following:

21   size_t getSize( float *ptr, int sizeOfTheArray )
22   {
23      return sizeof( ptr );
24  
25      } /* end function getSize */26      

is it correct?

ASKER CERTIFIED SOLUTION
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
An alternative (although I don't think it's better) is to use a sentinel value at the end of the array (as I mentioned earlier). Decide on a value that signifies the end of the array, and then you can just count :


size_t getSize(float *ptr) {
    size_t size = 0;
 
    while (ptr[size] != SENTINEL) ++size;
 
    size *= sizeof(*ptr);
 
    return size;
}

Open in new window

SENTINEL has to be replaced with the chosen sentinel value of course.