I have this following code, which has pointer variable pointer to an 2D array.
int main()
{
int (*ptr)[2][3];
printf("%u\n", sizeof(ptr)); // ---> give size of pointer = 8
printf("%u\n", sizeof(*ptr)); // ---> give size of array = 24, how it works adding * to ptr gives array size
return 0;
}
CodePudding user response:
You have to use the conversion specifier %zu
with values returned by the operator sizeof
that have the type size_t
.
printf("%zu\n", sizeof(ptr));
^^^^^
If you have a pointer like
T *p;
where T
is some type then the expression *p
has the type T
. So sizeof( *p )
is equivalent to sizeof( T )
.
This declaration
int (*ptr)[2][3];
declares a pointer to the array type int[2][3]
; You could rewrite the declaration with using a typedef the following way
typedef int T[2][3];
T *ptr;
So the expression sizeof( *ptr )
is equivalent to the expression sizeof( int[2][3] )
.
CodePudding user response:
sizeof(ptr)
is giving the size of the poiter itself which is 8
in your system
sizeof(*ptr)
is giving you the size of the object referenced by the pointer ptr
. As ptr
is a pointer to the 2D array of 6
integers (3x2) then the size of that array is 24
bytes assuming the sizeof(int) == 4
CodePudding user response:
The expression ptr
has type int (*)[2][3]
(pointer to 2-element array of 3-element array of int
) - it is a pointer type, so it's however big a pointer type is on your system (in this case, 8 bytes).
The expression *ptr
has type int [2][3]
- it's a 2x3 array of int
, meaning it's big enough to store 6 int
objects. An int
is 4 bytes wide on your system, for a total size of 24 bytes.
If the operand of sizeof
is an expression instead of a type name, it goes by the type of the expression. For example, the expression 1
has type int
, the expression 2
has type int
, and the expression 1 2
has type int
, so
sizeof 1 == sizeof 2 == sizeof (1 2) == sizeof (int)
Remember that sizeof
is an operator, not a function - you only need to use parentheses if the operand is a type name (like (int)
) or if the operand is an expression containing operators of lower precedence. For example
sizeof 1 2
will be parsed as
(sizeof 1) 2
because the arithmetic
operator has lower precedence than the unary sizeof
operator, which is probably not what you want. However, expressions like
sizeof *foo[N]
will be parsed as
sizeof (*(foo[N]))
so parentheses aren't necessary in that case. Some people will advise you to always use parentheses regardless, which isn't bad advice; eventually you'll learn when they aren't necessary and can be comfortable leaving them out.
CodePudding user response:
The sizeof() is known at compile time and calculated by the compiler. Compiler knows that you have a type of 2x3 32bit integer which is a total of 24 bytes. When you take pointer to this type, the size of this pointer, much like any other pointer is 8 bytes on 64bits system. So sizeof() any pointer will be 8 bytes. This is unrelated to the size of compile time structure, or array of predefined size.
Note: Array and pointer are a bit miss-leading in C. If you have an array of int arr[3], compiler knows that the size is 3*4 bytes. but if you pass it to a function as argument "arr[]" or just assign it to pointer like "int *ptr = &arr[0]" the size will become 8. Even though, pointer and array point to exactly the same area in the memory, the type itself is different. This type (pointer to byte, pointer to double, array of...) is maintained by the compiler and used to generate correct assembly code.