Is the pointer an integer?

If I know the address of the data object, can I store the address as an integer and use 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;

issues a warning:

Initialization makes integer from pointer without a cast

      

However, the program prints 101010

.

+3


source to share


5 answers


The standard does not guarantee that such a cast will always work.

To store a pointer in integral type use intptr_t

(or its unsigned cousin uintptr_t

). It is guaranteed to convert pointers void *

to such types and converts back, getting the same value.



Please note that these types are optional.

+7


source


sizeof(long)

usually compiler-defined (obeys the underlying HW architecture).

sizeof(long*)

exposed 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

Thus:

  • With long b = p

    only 4 least significant bytes p

    copied intob

  • With *(long*)b

    you are potentially trying to access an invalid memory address

In this example, if the 4 most significant bytes p

are zero, then "no harm will be done." But since this is not guaranteed when sizeof(long) != sizeof(long*)

this code is usually unsafe.



In addition to this, even if sizeof(long) == sizeof(long*)

, you still shouldn't use this type of conversions (pointer-to-integer) to keep your code portable across platforms.


UPDATE

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

also insecure.

Mostly use "%ld"

for values long

and "%lld"

for values long long

.

If sizeof(long) < sizeof(long long)

, this can lead to a memory access violation at runtime.

+1


source


To be safe, we must consider it unsafe.

The size of the pointer on the bit system n

is n

bits. For example, the pointer size must be 8 bytes on any 64-bit architecture / compiler. This is guaranteed.

However, there is no such guarantor for data types. Its highly compiler dependent. In your case, both are just the same size, so it works.


EDIT:

For warning

Initialization makes integer from pointer without a cast

      

Your compiler is very good at generating the warning. Check the data type. The variable is int *

not equal to the variable int

. In your case, this only works because in your specific case / implementations the lengths are the same.

0


source


The values p

and are the b

same, only p

can be accessed a

. I can point to a

, b

cannot point to a

. Because it is p

declared as a pointer. b

declared as a variable.

You cannot access a

via b

. Then how does your question fit. The b

address is a

treated as just value

not a address

, because it b

is a variable, not a pointer.

Even he prints 101010

, this program is not generic.

0


source


A pointer is a variable whose value is the address of another variable. Like any variable or constant, you must declare a pointer before you can work with it. The general form of declaring a pointer variable is:

type *var-name;

      

The actual data type for all pointers, whether integer, float, character, or other, is the same long hexadecimal number that represents the memory address. The only difference between pointers of different data types is the data type of the variable or constant that the pointer points to.

Pointers are usually of a fixed size, eg. in a 32-bit executable, they are usually 32-bit. There are a few exceptions, for example in old 16-bit windows, when you needed to distinguish between 32-bit pointers and 16-bit pointers ... It is usually quite safe to assume that they will be the same within a given executable on modern desktop OSs.

-1


source







All Articles