我可以通过C ++中的(unsigned)char *读取任何可读的有效内存位置吗?

时间:2011-07-09 12:51:57

标签: c++ string pointers void-pointers memory-access

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

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

举例来说:

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

免责声明:这个问题纯属学术问题。我不打算把它放到生产代码中!通过 legal 我的意思是,如果它真的是 legal 根据标准,那就是它可以在所有实现的100%上工作。 (不仅仅是在x86或一些常见的硬件上。)

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

3 个答案:

答案 0 :(得分:6)

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

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

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

static_cast执行编译时类型检查,因此不太可能始终有效。在这种情况下,您需要reinterpret_cast

答案 1 :(得分:2)

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

  

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

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

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

答案 2 :(得分:0)

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