Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 363
  • Last Modified:

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???

0
suoju1
Asked:
suoju1
  • 6
  • 4
  • 4
  • +2
1 Solution
 
AxterCommented:
Because sizeof returns the size of the variable, and not the size of the array.

4 bytes is the size of a pointer.
0
 
Infinity08Commented:
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.
0
 
AxterCommented:
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.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
suoju1Author Commented:
but how come the sizeof( array ) do?
0
 
AxterCommented:
>>but how come the sizeof( array ) do?

because variable array is not a pointer, where as variable ptr is a pointer.
0
 
suoju1Author Commented:
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.
0
 
peetmCommented:
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
0
 
Infinity08Commented:
>> 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 */
0
 
peetmCommented:
>>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].
0
 
evilrixSenior Software Engineer (Avast)Commented:
>> 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
0
 
peetmCommented:
>>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.
0
 
evilrixSenior Software Engineer (Avast)Commented:
>> sizeof now evaluates at runtime is with C99s variable sized arrays.
Yes, for that exception you are right -- thanks for clarifying that peetm.
0
 
evilrixSenior Software Engineer (Avast)Commented:
0
 
AxterCommented:
>>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.
0
 
evilrixSenior Software Engineer (Avast)Commented:
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

0
 
suoju1Author Commented:
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      
0
 
evilrixSenior Software Engineer (Avast)Commented:
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

0
 
suoju1Author Commented:
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?

0
 
evilrixSenior Software Engineer (Avast)Commented:
Well no! That will still only return the size of ptr not the size of the array! Since you are passing in the size of the array it'll be as below. You need to multiply the size of an element (in bytes) by the number of elements.

In this case a float is 4 bytes and there are 10 elements, so 4 x 10 == 40 bytes.
size_t getSize( float *ptr, int sizeOfTheArray )
{
	size_t size = 0;
 
	if(ptr && (sizeOfTheArray > 0))
	{
		size = sizeof(ptr[0]) * sizeOfTheArray;
	}
 
	return size;
}
 
int main()
{
	float x[10] = {0};
	size_t size = getSize(x, 10);
	return 0;
}

Open in new window

0
 
Infinity08Commented:
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

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

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 6
  • 4
  • 4
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now