Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sizeof &a vs *a

Tags:

c

sizeof

I searched thoroughly but could not find the solution to this: Assuming sizeof(int) = 4, we define:

int a[10] = {0};

What is the output of the following:
1. sizeof(&a)
2. sizeof(*a)
3. sizeof(a)

I know that sizeof(a) is equal to sizeof(int) * 10 = 40.
I also understand that *a is actually a the first element in the array, therefore sizeof(*a) is actually size of the int which resides in there, i.e. 4.

However, after running the code, I do not understand why size of &a is 8. I know that the '&' operator returns the address of the variable a, but why the sizeof the address is 8?

like image 875
Tegernako Avatar asked Aug 08 '19 07:08

Tegernako


People also ask

What is the use of sizeof in C++?

It is a compile-time unary operator and used to compute the size of its operand. It returns the size of a variable. It can be applied to any data type, float type, pointer type variables. When sizeof () is used with the data types, it simply returns the amount of memory allocated to that data type.

When sizeof () is used with the expression?

When sizeof () is used with the expression, it returns size of the expression. Let see example: As we know from first case size of int and double is 4 and 8 respectively, a is int variable while d is a double variable. The final result will be a double, Hence the output of our program is 8 bytes.

What is the result when sizeof is 0?

The result of sizeof is always nonzero, even if applied to an empty class type. When applied to an expression, sizeof does not evaluate the expression, and even if the expression designates a polymorphic object, the result is the size of the static type of the expression.

What is the sizeof operator in C?

The sizeof operator is the most common operator in C. It is a compile-time unary operator and used to compute the size of its operand. It returns the size of a variable. It can be applied to any data type, float type, pointer type variables. When sizeof() is used with the data types, it simply returns the amount of memory allocated to that data ...


2 Answers

The size of the address depends on your architecture and is not directly related to the size of an int itself. So it’s 8 in your case, which seems pretty normal (64 bits).

like image 172
Michael Piefel Avatar answered Nov 15 '22 06:11

Michael Piefel


The key to understanding this is to know that arrays usually "decay" into pointers to the first element, whenever they are used in an expression. Except for some special cases. The rule of array decay and the exceptions are found in the C standard (C17 6.3.2.1/3):

Except when it is the operand of the sizeof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue.

As we can see, sizeof and & are exceptions to the rule.

This means that a in sizeof(&a) does not decay to a pointer. We can know this because sizeof and unary & are both unary operators with the same precdence, but with right-to-left operator associativity. Meaning that &a gets interpreted first and there is no array decay when & is used.

So we get the address of the array. In your case, the size of an int pointer of type int(*)[10]. What size a pointer got has nothing to do with the size of an int, but it is likely to be either 4 or 8 bytes on 32 and 64 bit systems respectively.

In case of sizeof(*a), then just like in the &a case, the rigth-to-left associativity of unary operators means that *a gets interpreted first. And so the array does decay into a pointer to the first element, before sizeof is applied. So *a gives the size of the first element, which is the size of an int.

And finally in case of sizeof(a) there is no array decay since a is used with sizeof and no other operator is present. Meaning we get the size of the whole array.

like image 28
Lundin Avatar answered Nov 15 '22 07:11

Lundin