【问题标题】:C++ how to get the address stored in a void pointer?C ++如何获取存储在void指针中的地址?
【发布时间】:2010-12-08 07:01:06
【问题描述】:

如何获取指针指向的值的内存地址?就我而言,它是一个空指针。 只是将它分配给一个 uint 会给我这个错误:

Error   1   error C2440: 'return' : cannot convert from 'void *' to 'UInt32'

谢谢!

【问题讨论】:

  • 您已经拥有该地址。这就是指针是。您的意思是“我怎样才能获得 C++ 将地址映射到的整数”。 ;)
  • 如果要打印值,只需打印 void*。如果您想要地址,请保留 void*。如果您想要一个 void* 变量的地址,请将其分配给 void*。

标签: c++ pointers void


【解决方案1】:
std::size_t address = reinterpret_cast<std::size_t>(voidptr);
// sizeof(size_t) must be greater or equal to sizeof(void*)
// for the above line to work correctly.

@Paul Hsieh
我认为在这个特定问题中将void* 转换为size_t 就足够了,原因有以下三个:

  • 提问者没有说明他是否 是否需要便携式解决方案。他 说,这对他有用。我不知道具体是什么 这意味着但是 我很清楚他是 在 Windows 或其他平台上处理 IA-32 系统处于保护模式。那 意味着将指针转换为 整数是一个定义的操作 即使它不是由标准 C++ 定义的系统。

  • 其次,我建议首先将指针转换为int,这显然没有意义,正如 litb 和 jalf 向我展示的那样。我纠正了我犯的错误,并将int替换为size_t。

  • 最后,我努力寻找与您在标准中提出的解决方案相关的内容。不幸的是,我找不到任何相关的东西。我有这个参考:ANSI ISO IEC 14882 2003。我认为sellibitze 指出它将成为未来标准的一部分。我真的不了解C,显然C99引入了这个完美的解决方案。我希望有人向我展示 C++ 中的可移植解决方案。

请不要犹豫,纠正我的错误,我还是大学的学生 :)

谢谢,

【讨论】:

  • 在 64 位系统上 sizeof(int) != sizeof (void *)
  • 只有当整数类型“足够大”以使往返指针->整数->指针是无损的时,从指向其中一种整数类型的指针进行的 reinterpret_cast 才是格式正确的。跨度>
  • 在实践中,size_t 在大多数盒子上应该足够大(但理论上不能保证)。
  • 即使我们忽略 int 可能小于 void* 的问题,您也可以至少使用无符号数据类型。 ;) 负地址没有真正意义。
  • "...而 ptrdiff_t...显然 [必须] 覆盖整个指针空间范围"。 @Paul:我不这么认为。该语言的内存模型是“一个或多个连续字节序列”。指针算术仅限于来自相同“序列”的指针。我认为 ptrdiff_t 不必大到足以容纳指针。
【解决方案2】:

指针,在 C 和 C++ 中是以某种抽象形式体现的内存地址。您可以将指针的特定于实现的字符串解释为:

printf ("%p", voidPointer);

另一种方法是将其强制转换为 intptr_t:

(intptr_t) voidPointer;

C++ 中的 NULL 指针被定义为等于“0”,所以在上面的操作中你可能会得到 (intptr_t) 0 的等值。但是,这仍然取决于您以及您必须将其解释为内存地址的任何实现特定知识。

关键是在使用奇异内存模型的平台中,例如 16 位 x86 DOS 编译器,其内存模型具有带偏移量的段,指针可以以多种方式解释。在原始地址表示中,NULL 可以是 DS:0 或 SS:0 而不仅仅是普通的 0。

【讨论】:

  • intptr_t 还不是 C++ 的一部分。无论如何,您确定标准保证 (intptr_t)voidPointer 在 voidPointer 是空指针并且 intptr_t 是足够大的整数的正确 typedef 的情况下评估为 0 吗?我认为不会。它只是说,如果一个指针被强制转换为另一个指针,则空指针值将映射到空指针值。但是某个指针的空指针值实际上可能表示为 0xDEADBEEF 之类的东西——不一定是整数零。
  • -1 当然,C++ 中不能保证(integer-type)null-pointer 的计算结果为0。您将“NULL”与“空指针”混淆了。阅读stackoverflow.com/questions/423823/…
【解决方案3】:

你需要一个演员——要么是reinterpret_cast(最好):

UInt32 address = reinterpret_cast<UInt32>( voidPointer );

或 C 风格的演员表(真的不推荐):

UInt32 address = (UInt32)voidPointer;

【讨论】:

  • 我会在 sizeof(UInt32) == sizeof(void *) 上添加一个(BOOST)静态断言
【解决方案4】:

您可以使用 sprintf() 获取地址的字符串表示形式,或者使用 %p 格式说明符使用 printf() 显示它,例如:

printf( "%p", voidptr ) ;

如果您只想对地址执行指针运算,请将其转换为适当的具体数据类型指针,否则将其转换为已建议的整数。

【讨论】:

    【解决方案5】:

    在 C++ 中,我能够打印指向的地址:

    cout << "Address: " << ((unsigned)my_ptr);
    

    【讨论】:

      猜你喜欢
      • 2019-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      相关资源
      最近更新 更多