简体   繁体   English

获取指针的地址为其分配一个值

[英]Getting the address of a pointer assigns it a value

I'm testing pointers with C++ and I just noticed that when I do something like this:我正在用 C++ 测试指针,我只是注意到当我做这样的事情时:

int main(){
int* test;
std::cout << test << std::endl;

return 0;
}

it would output 0 and when I do something like this:它会输出 0,当我做这样的事情时:

int main(){
int* test;
&test;
std::cout << test << std::endl;

return 0;
}

it outputs a valid memory address.它输出一个有效的内存地址。 Does anyone have an idea on why this happens?有没有人知道为什么会发生这种情况?

tl;dr: Compilers are complex, and undefined behaviour allows them to do all sorts of things. tl;dr:编译器很复杂,未定义的行为允许它们做各种各样的事情。


 int* test; std::cout << test << std::endl;

Using test (even just to evaluate its own value!) in this manner when it hasn't been given a value is not permitted, so your program has undefined behaviour.不允许以这种方式使用test (甚至只是为了评估它自己的值!)在没有被赋予值的情况下,因此您的程序具有未定义的行为。

Your compiler apparently uses this fact to take some particular path.您的编译器显然使用这个事实来采取一些特定的路径。 Perhaps it's assuming a zero value, or it's prepared to optimise away the variable and leave you only with some hardcoded thing.也许它假设一个零值,或者它准备优化掉变量,只留下一些硬编码的东西。 It's arbitrarily picked zero for that thing, because why not?它为那件事随意选择了零,因为为什么不呢? The value is unspecified by the standard, so that's fine.标准未指定该值,所以没关系。

 &test;

This is another thing.这是另一回事。 It is perfectly legal to take the address of an uninitialised thing, so this aspect of your program is well-defined.取一个未初始化的东西的地址是完全合法的,所以你的程序的这方面是明确定义的。 It appears that this triggers a path in the compiler that prepares to create actual, honest-to-god storage for the pointer.似乎这会触发编译器中的一个路径,该路径准备为指针创建实际的、诚实的存储。 This odr-use effectively prevents any of the optimise-it-out machinery.这种 odr-use 有效地阻止了任何优化它的机器。 Somehow, that's taken it down a road that doesn't trigger the "pretend it's zero" case, and you end up with (possibly) some actual, memory read instead;不知何故,这使它走上了一条不会触发“假装为零”情况的道路,而您最终(可能)会读取一些实际的内存; that memory read results in the unspecified value that you have come to expect from outputting uninitialised things.内存读取会导致您从输出未初始化的东西中得到未指定的值。

That value is still "garbage", though.但是,该值仍然是“垃圾”。 You indicate that you "can" deference it, that you "can" memmove it, that you "can" work with it without triggering a segmentation fault.你表明你“可以”尊重它,你“可以”记住它,你“可以”在不触发分段错误的情况下使用它。 But this is all an illusion!但这一切都是错觉! Do not "expect" segmentation faults from the use of invalid pointers.不要“期望”因使用无效指针而出现分段错误。 That is only one possible result.这只是一种可能的结果。 The operating system doesn't detect all bad accesses (unless you use some debug tool to make it do so), usually only those that cross page boundaries or such.操作系统不会检测到所有的错误访问(除非您使用某种调试工具来实现),通常只会检测那些跨越页面边界或类似的访问。

Anyway, the specifics of the above are complete speculation but it shows the sort of factors that can go into different outcomes of programs with undefined behaviour.无论如何,上述细节完全是推测,但它显示了可能影响具有未定义行为的程序的不同结果的因素。 Ultimately there is not a lot of point in trying to rationalise about this sort of code, and there is certainly no point in writing it!最终,试图对这种代码进行合理化并没有什么意义,而且编写它当然也没有意义!

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

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