如何将 unsigned int 转换为指针并取消引用它?

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

我正在尝试类似的东西:

#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);
}

但是在取消引用 p 时出现 分段错误(核心已转储),有人知道如何将 unsigned int 转换为指针并取消引用吗?

我正在使用 gcc 版本 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04).

这在 64 位系统上会失败,因为指针有 8 个字节长,而 int 只有 4 个字节长。这意味着您将丢失转换中的最后四个字节数据,从而创建一个无效指针。

您的代码应该是这样的:

#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);
}

如果您坚持转换为整数,那么这可能是一个可能的解决方案:

#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);
}

注意:您实际上应该只使用标准指针。 long long 的大小不被 C 编译器保证,并且此代码缺乏可读性。

int 和指针类型之间的转换带有实现定义的方面。整数类型可能太小而无法包含指针,反之亦然。

因此发明了整数类型uintptr_t(stdint.h)。这是一种保证足够大的类型,可以移植地为特定系统保存转换后的指针值。所以你应该把 unsigned int 换成 uintptr_t (不像 unsigned long long 等是便携类型)

#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);
}

(使用 printf 可移植地打印 uintptr_t 需要来自 inttypes.h 的这个看起来很奇怪的宏 PRIuPTR。这个扩展为类似 "llu" 的东西。)