Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is pointer just an integer?

If I know the address of an data object, could I store the address as an integer and operate the integer as a pointer?

For example,

void main(){
    long a = 101010;
    long *p = &a;
    long b = p;
    printf("%lld\n", *(long*)b);
}

Is it always safe?

Comments: long b = p; produces a warning:

Initialization makes integer from pointer without a cast

However, the program prints 101010.

like image 856
Min Fu Avatar asked Nov 29 '14 07:11

Min Fu


People also ask

What's the difference between pointer and integer?

'Integer' in a programming language can be defined as any data type representing a mathematical subset. On the other hand, 'pointer' can be defined as a type that refers or points to another value which is stored in some part of the memory of the computer. Integers exist mainly as binary value in a computer system.

Is pointer is a datatype?

Pointer is a data type and the purest form of it in C is void *. A void * can pass the memory address around which is what a pointer does but it cannot be dereferenced. Dereferencing means to get at the data contained at the memory location the pointer is pointing at.

What type of value is a pointer?

A pointer variable (or pointer in short) is basically the same as the other variables, which can store a piece of data. Unlike normal variable which stores a value (such as an int, a double, a char), a pointer stores a memory address. Pointers must be declared before they can be used, just like a normal variable.

Can a pointer be any type?

Every pointer is of some specific type. There's a special generic pointer type void* that can point to any object type, but you have to convert a void* to some specific pointer type before you can dereference it.


2 Answers

It's not guaranteed by the standard that such cast would always work.

To store a pointer in an integral type, use intptr_t (or its unsigned cousin uintptr_t). It's guaranteed to convert void * pointers to such types and convert back, resulting the same value.

Note that these types are optional.

like image 188
Yu Hao Avatar answered Oct 13 '22 01:10

Yu Hao


sizeof(long) is typically defined by the compiler (subjected to the underlying HW architecture).

sizeof(long*) is subjected to the size of the virtual memory address space on your platform.

For example, with the Visual Studio compiler for 64-bit operating system and x64-based processor:

  • sizeof(long) == 4
  • sizeof(long*) == 8

Therefore:

  • With long b = p, only the 4 least significant bytes of p are copied into b
  • With *(long*)b, you are potentially attempting to access an invalid memory address

In this example, if the 4 most significant bytes of p are zero, then "no harm is done". But since it is not guaranteed to be the case, when sizeof(long) != sizeof(long*) this code is generally unsafe.

In addition to that, even if sizeof(long) == sizeof(long*), you should still refrain from using this type of conversions (pointer-to-integer), in order to keep your code portable to other platforms.


UPDATE

Please note that printf("%lld\n", *(long*)b) is also unsafe.

You should basically use "%ld" for long values and "%lld" for long long values.

If sizeof(long) < sizeof(long long), then it may lead to a memory access violation during runtime.

like image 36
barak manos Avatar answered Oct 13 '22 01:10

barak manos