如何将 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"
的东西。)
我正在尝试类似的东西:
#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"
的东西。)