简体   繁体   中英

How to cast a unsigned int to a pointer and dereference it?

I'm trying something like:

#include <stdio.h>

int main(void)
{
    unsigned int x = 701;
    unsigned int p = (unsigned int) &x;

    printf("Original ptr: %u\n", p);
    printf("Dereferencing ptr: %u\n", *(int *) p);
}

but get Segmentation fault (core dumped) while dereferencing p , does any know how to cast an unsigned int to a pointer and dereferencing it?

I'm using gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04) .

This will fail on 64 bit systems, because a pointer is 8 bytes long, but an int is only 4 bytes long. This means that you are losing the last four bytes of data in the cast, creating an invalid pointer.

This is how your code should look:

#include <stdio.h>
#include <stdint.h>

int main(void)
{
    unsigned int x = 701;
    unsigned int *p = &x;

    printf("Original ptr: %u\n", p);
    printf("Dereferencing ptr: %u\n", *p);
}

And if you insist on casting to integers, then this could be a possible solution:

#include <stdio.h>
#include <stdint.h>

int main(void)
{
    unsigned int x = 701;
    unsigned long long p = (unsigned long long) &x;

    printf("Original ptr: %u\n", p);
    printf("Dereferencing ptr: %u\n", *(int *) p);
}

Note: you should really just be using standard pointers. The size of a long long is not guaranteed by the C compiler, and this code lacks readability.

Converting between int and pointer types comes with implementation-defined aspects. The integer type might be too small to contain a pointer or vice versa.

Therefore the integer type uintptr_t (stdint.h) was invented. This is a type guaranteed to be large enough to hold a converted pointer value for the specific system, portably. So you should switch unsigned int with uintptr_t (which unlike unsigned long long etc is a portable type)

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(void)
{
    unsigned int x = 701;
    uintptr_t p = (uintptr_t) &x;

    printf("Original ptr: %" PRIuPTR "\n", p);
    printf("Dereferencing ptr: %u\n", *(unsigned int*)p);
}

(Printing a uintptr_t with printf portably requires this weird-looking macro PRIuPTR from inttypes.h. This one expands to something like "llu" .)

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