简体   繁体   English

我可以通过 C++ 中的(无符号)char* 读取任何可读的有效 memory 位置吗?

[英]Can I read any readable valid memory location via a (unsigned) char* in C++?

My search foo seems lacking today.我的搜索 foo 今天似乎缺少。

I would like to know if it is legal according to std C++ to inspect "any" memory location via an (unsigned(?)) char*.我想知道根据标准 C++ 通过 (unsigned(?)) char* 检查“任何”memory 位置是否合法 By any location I mean any valid address of an object or array (or inside an array) inside the program.任何位置是指程序内 object 或数组(或数组内)的任何有效地址。

By way of example:例如:

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

Disclaimer : This question is purely academical.免责声明:这个问题纯粹是学术性的。 I do not intend to put this into production code!我不打算把它放到生产代码中! By legal I mean if it's really legal according to the standard, that is if it would work on 100% of all implementations.合法我的意思是如果根据标准它真的是合法的,那就是它是否适用于所有实现的 100%。 (Not just on x86 or some common hardware.) (不仅在 x86 或一些常见硬件上。)

Sub-question: Is static_cast the right tool to get from the void* address to the char* pointer?子问题: static_cast是从 void* 地址到 char* 指针的正确工具吗?

C++ assumes strict aliasing, which means that two pointers of fundamentally different type do not alias the same value. C++ 假定严格别名,这意味着根本不同类型的两个指针不会别名相同的值。

However, as correctly pointed out by bdonlan, the standard makes an exception for char and unsigned char pointers.但是,正如 bdonlan 正确指出的那样,该标准对charunsigned char指针进行了例外处理。

Thus, in general this is undefined behaviour for any pointer type to read any deliberate address (which might be any type), but for the particular case of unsigned char as in the question it is allowed (ISO 14882:2003 3.10(15)).因此,一般来说,对于任何指针类型读取任何故意地址(可能是任何类型),这是未定义的行为,但对于问题中允许unsigned char的特殊情况(ISO 14882:2003 3.10(15)) .

static_cast does compile-time type checking, so it is unlikely to always work. static_cast进行编译时类型检查,因此不太可能总是有效。 In such a case, you will want reinterpret_cast .在这种情况下,您将需要reinterpret_cast

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

7. An object shall have its stored value accessed only by an lvalue expression that has one of the following types: 7. object 的存储值只能由具有以下类型之一的左值表达式访问:

  • a type compatible with the effective type of the object,与 object 的有效类型兼容的类型,
  • [...] [...]
  • a character type字符类型

So it is legal (in C) to dereference and examine a (valid) pointer via unsigned char .因此,通过unsigned char取消引用和检查(有效)指针是合法的(在 C 中)。 However, the contents you'll find there are unspecified;但是,您将在那里找到的内容未指定; tryToFigureOutWhatThisIs has no well-defined way of actually figuring out what it's looking at. tryToFigureOutWhatThisIs没有明确定义的方法来实际弄清楚它在看什么。 I don't have a copy of the C++ spec here, but I suspect it uses the same definition, in order to maintain compatibility.我在这里没有 C++ 规范的副本,但我怀疑它使用相同的定义,以保持兼容性。

You can only use a char* , not an unsigned char* .您只能使用char* ,而不能使用unsigned char* Using an unsigned char* will break strict aliasing rules and invoke undefined behaviour, but there is an exception for char* .使用unsigned char*会破坏严格的别名规则并调用未定义的行为,但char*有一个例外。 However, trying to actually do anything with the memory you read is very highly dubious and very likely to do something undefined.然而,试图用你读到的 memory 做任何事情是非常可疑的,很可能会做一些未定义的事情。 That's why it's rarely done in idiomatic C++ code.这就是为什么它很少在惯用的 C++ 代码中完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM