7

我的搜索 foo 今天似乎缺少。

我想知道根据 std C++ 通过 (unsigned(?)) char* 检查“任何”内存位置是否合法。任何位置是指程序内对象或数组(或数组内)的任何有效地址。

例如:

void passAnyObjectOrArrayOrSomethingElseValid(void* pObj) {
   unsigned char* pMemory = static_cast<unsigned char*>(pObj)
   MyTypeIdentifyier x = tryToFigureOutWhatThisIs(pMemory);
}

免责声明:这个问题纯粹是学术性的。我不打算把它放到生产代码中!合法我的意思是如果根据标准它真的是合法的,那就是它是否适用于所有实现的 100%。(不仅仅是在 x86 或一些常见的硬件上。)

子问题:static_cast从 void* 地址到 char* 指针的正确工具是什么?

4

3 回答 3

8

C++ 假定严格别名,这意味着根本不同类型的两个指针不会别名相同的值。

但是,正如 bdonlan 正确指出的那样,该标准对charunsigned char指针进行了例外处理。

因此,一般来说,对于任何指针类型读取任何故意地址(可能是任何类型)来说,这是未定义的行为,但对于unsigned char问题中的特定情况,它是允许的(ISO 14882:2003 3.10(15))。

static_cast进行编译时类型检查,因此它不太可能总是有效。在这种情况下,您将需要reinterpret_cast.

于 2011-07-09T13:02:04.690 回答
2

根据 ISO/IEC 9899:1999 (E) §6.5/7:

 7. 对象的存储值只能由具有以下类型之一的左值表达式访问:

  • 与对象的有效类型兼容的类型,
  • [...]
  • 字符类型

因此,通过取消引用和检查(有效)指针是合法的(在 C 中)unsigned char。但是,您将在那里找到的内容未指定;tryToFigureOutWhatThisIs没有明确定义的方法来实际弄清楚它在看什么。我这里没有 C++ 规范的副本,但我怀疑它使用相同的定义,以保持兼容性。

于 2011-07-09T15:55:56.023 回答
0

您只能使用一个char*,而不是一个unsigned char*。使用 anunsigned char*将打破严格的别名规则并调用未定义的行为,但char*. 然而,试图用你读到的内存做任何事情是非常可疑的,而且很可能会做一些未定义的事情。这就是为什么它很少在惯用的 C++ 代码中完成。

于 2011-07-09T13:06:03.380 回答