简体   繁体   中英

where the size of pointer variable gets stored?

 #include <stdio.h>

 int main(void)
 {
int a[5]={1,2,3,4,5};
int *ptr=(int*)(&a+1);
printf("%d %d\n",*(a+1),*(ptr-1));
return 0;
}

output:

2 5

Here in the statement *ptr= (int*)(&a+1) 1 is not added to the &a . Actually its like &a + sizeof(a) . Now my question is where size of the pointer variable is stored or if it is not stored then how it is calculated. In case of int, float, char etc their size is predefined in compiler so int *a is a different case. Is it true that only the adress is stored in a pointer variable nothing else?. where the metadata about pointer variable gets stored?

Due to your variable declaration int a[5] = ... , the compiler knows that a is of type int [5] (hence, sizeof(a) would return 20). Since the compiler knows the type of a , taking the address of a will yield a pointer of the right type. This might be a bit surprising: &a does not yield an int** but rather a int (*)[5] (a pointer to an array of five integers).

So when executing

int *ptr=(int*)(&a+1);

You take the address of a , add one (which, due to the way C/C++ pointer arithmetics work, increases the address referenced by the pointer by sizeof(a) bytes) and then cast the result to an int. So at this point, ptr points behind the last element of the array (at offset 20).

You then cast the pointer to int* and use *(ptr-1) , so you dereference the int value at offset 16 - which happens to be where the last array element is.

It doesn't get stored. The compiler certainly needs to keep track of this when it compiles the code, but after that, it is basically just hard-coded into the generated instructions.

&a is of type int (*)[5] , ie, &a is a pointer to an array , NOT a pointer to int. The compiler knows (obviously) what the array size is, and uses it for pointer arithmetic.

A pointer has a "double type". On one hand, it's a pointer with its own size (let's say 4 bytes for every pointer on some systems). On the other hand, it's a pointer to something that has a size (apart from void * ).

Types in general are not directly accessible in C. You can't ask "what is the type of a variable".

But the size is always accessible through sizeof . So int * itself may use 4 bytes, but the compiler knows that it's pointing to an integer, and it knows the size of the integer. For struct xyz * , the pointer itself may again be 4 bytes, but the compiler knows that it's pointing to a structure, and it knows the size of the structure. What's important is that the pointer has a type beyond "pointer".

So, if you define struct xyz *ptr , you can always find out the size of what the pointer is pointing to, by checking sizeof(*ptr) . You can do that even if ptr is not initialised.

The only thing you can't do is check sizeof(*ptr) when ptr is defined void * .

In terms of "metadata", it's all in the type of the pointer.

A pointer is only a memory address, there is no metadata. Adding N to pointer of type T* results in adding N*sizeof(T) to the address value. Compiler knows size of every type during compilation, nothing is stored.

  • a+1 points to the second int in a, because it treats a as int* ie the pointer to the first element, ie sizeof(int) is added to the memory address
  • &a+1 points to the “second int[5] array”, ie sizeof(int[5]) is added to the memory address
  • ptr-1 points to an int right before the first element of the “second array”, ie the last element of a.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM