获取指针的地址为其分配一个值 [英] Getting the address of a pointer assigns it a value

查看:61
本文介绍了获取指针的地址为其分配一个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 C++ 测试指针,我刚刚注意到当我做这样的事情时:

int main(){int* 测试;std::cout <<测试<

它会输出 0,当我做这样的事情时:

int main(){int* 测试;&测试;std::cout <<测试<

它输出一个有效的内存地址.有没有人知道为什么会发生这种情况?

解决方案

tl;dr:编译器很复杂,未定义的行为允许它们做各种各样的事情.

<小时><块引用>

int* 测试;std::cout <<测试<

不允许以这种方式使用 test(甚至只是为了评估它自己的值!)在没有被赋值的情况下,所以你的程序有未定义的行为.

你的编译器显然使用这个事实来采取一些特定的路径.也许它假设一个零值,或者它准备优化掉变量,只留下一些硬编码的东西.它为那件事随意选择了零,因为为什么不呢?标准未指定该值,所以没问题.

<块引用>

&test;

这是另一回事.取一个未初始化的东西的地址是完全合法的,所以你的程序的这方面是明确定义的.似乎这会触发编译器中的一个路径,该路径准备为指针创建实际的、诚实的存储.这种 odr-use 有效地阻止了任何优化它的机器.不知何故,这使它走上了一条不会触发假装为零"情况的道路,而您最终(可能)会读取一些实际的内存;内存读取会导致您期望从未初始化的内容中获得未指定的值.

尽管如此,该值仍然是垃圾".你表明你可以"尊重它,你可以"记住它,你可以"在不触发分段错误的情况下使用它.但这一切都是错觉!不要期望"因使用无效指针而出现分段错误.这只是一种可能的结果.操作系统不会检测到所有的错误访问(除非您使用某种调试工具来实现),通常只会检测那些跨越页面边界或类似的访问.

无论如何,上述细节完全是推测,但它显示了可能影响具有未定义行为的程序的不同结果的因素.归根结底,试图对这类代码进行合理化并没有什么意义,而且编写它当然也毫无意义!

I'm testing pointers with C++ and I just noticed that when I do something like this:

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

return 0;
}

it would output 0 and when I do something like this:

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.


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.

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. 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!

这篇关于获取指针的地址为其分配一个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆