【问题标题】:Convert char* to int memory address将 char* 转换为 int 内存地址
【发布时间】:2020-12-08 02:46:38
【问题描述】:

我有:

char* mem = (char*) 0xB8000;

然后mem 被传递给一个函数。在函数内部,我想取回数字 0xB8000 并将其与其他一些整数进行比较。如何将mem 转换回原来的整数?

【问题讨论】:

标签: c pointers type-conversion


【解决方案1】:

要将任何指针转换为整数,请执行以下操作:

#include <stdint.h>

uintptr_t ptr_to_integer(const void *ptr) {
    return (uintptr_t) ptr;
}

请注意,uintptr_t 的大小可能因平台而异。这也是 C 标准的可选部分,因此从技术上讲,只有 uintmax_t 绝对是可移植的。

【讨论】:

  • 值得注意的是,uintptr_t 是 ISO C 标准的可选功能,因此它可能不适用于某些编译器。
  • @AndreasWenzel 你是对的。但是你会很难找到一个不提供这种类型或其他可选类型定义(如uint32_t)的编译器。
  • 高级问题:“只有 unsigned long long 才是绝对可移植的”--> 不完全是。 1) uintmax_t 会是更好的选择 2) unsigned long longuintmax_t 都没有指定足够宽来往返指针 - 但实际上是。 uintptr_t 的简单优势是,如果代码由于缺少它而无法编译,则可以肯定其他整数类型也将无法忠实地往返。
【解决方案2】:

如何将 mem 转换回原始整数?

通常转换为(u)intptr_t 将形成原始整数。

include <stdint.h>

printf("o: %lX\n", 0xB8000LU);
char* mem = (char*) 0xB8000;
printf("mem %p\n", (void *) mem);
uintptr_t i =  (uintptr_t) mem;
printf("i: %jX\n", (uintmax_t) i);

陷阱

C 没有指定循环跳闸 (u)intptr_tvoid *uintptr_t(或任何整数类型)以产生原始值。甚至void *(u)intptr_tvoid * 也只是指定返回一个等价 指针,不一定是相同的指针位模式。

未指定将任意数字(如(char*) 0xB8000)投射到指针上。

“结果是实现定义的,可能没有正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示”C17dr 6.3.2.3 5

(u)intptr_t可选 类型 - 虽然很常见。兼容的库可能无法提供该类型。

(u)intptr_t 没有对应的打印说明符。一个合理的解决方法是转换为最广泛的可用类型和打印。


我想取回数字 0xB8000 并将其与其他一些整数进行比较。

更好的方法可以将“其他整数”转换为 char * 并比较指针。

最适合 OP 发布更大的代码使用情况以处理总体目标。

谨慎行事。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-24
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    • 1970-01-01
    相关资源
    最近更新 更多