Is pointer just an integer?

落爺英雄遲暮 提交于 2020-12-09 05:09:32

问题


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.


回答1:


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.




回答2:


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.




回答3:


Even p value and b value are same, only p can access a i.e can to point a, b can not point to a. Because p is declared as pointer. b is declared as variable.

You cant access a through b. Then how is your question suitable. In b, address of a is treated as only value not aaddress, because of b is variable not a pointer..

Even it prints 101010, this program is not a generic.




回答4:


To be on safe side, we should consider it's not safe.

Size of a pointer on a n bit system is n bits. For example, size of a pointer should be 8 byte on any 64-bit architecture / compiler. That's guranteed.

However, there is no such gurantee for data types. Its heavily compiler dependent. In your case, both just happens to have the same size, that's why it works.


EDIT:

For the warning

Initialization makes integer from pointer without a cast

Your compiler is very much right for producing the warning. Please check the data type. An int * variable is not equal to an int variable. In your case, it works just because there lengths are same in your particular case / implementation.




回答5:


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 a pointer variable declaration is:

type *var-name;

The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is the same, a long hexadecimal number that represents a 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 generally have a fixed size, for ex. on a 32-bit executable they're usually 32-bit. There are some exceptions, like on old 16-bit windows when you had to distinguish between 32-bit pointers and 16-bit... It's usually pretty safe to assume they're going to be uniform within a given executable on modern desktop OS's.



来源:https://stackoverflow.com/questions/27199805/is-pointer-just-an-integer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!