我正在阅读变量的地址绑定,并想知道在任何情况下执行期间变量的地址是否会发生变化?它会由于 JVM 或 CLR 中的垃圾收集而发生吗?那么 C 和 C++ 呢?
7 回答
如果你的代码有未定义的行为,那么所有的赌注都没有了,是的,它可能会发生。
但在有效的 C/C++ 程序中,变量的地址不会改变。
这在很大程度上取决于语言以及更改地址的含义。在 C++ 中,对象的地址是唯一标识它的对象,它们不能移动。一些托管语言(包括 Java 和 C#)使用分代垃圾收集器,它们实际上在内存中移动对象(在分代 GC 中,对象会随着时间从一代移动到另一代),但事实是您不应该关心:那些你可以获得对象地址的语言,地址是固定的,在那些地址固定的语言中,它不是对象可感知状态的一部分......
另请注意,我在这里使用的是object,而不是 variable,因为我相信这是您感兴趣的。有一条细线将对象和变量分开,例如在Java中,引用是可以用来访问对象的变量。但我什至不会尝试进入任何一个的精确定义......
在一个有效的 C/C++ 程序中,除非您的代码故意或以其他方式更改变量的地址,否则执行环境不会更改该地址。
基本上,变量在程序的执行时间内继续引用相同的值或内存位置。但这可以更改,使其uninitialized
(具有未定义的值),因此尚未明确赋予它特定的值。这可能会产生不可预知的结果。为了处理这样的问题,内存中变量所需的空间可以仅在变量第一次使用时分配,在不再需要时释放。
在Java 中,某些类型的变量的地址可以改变(例如静态或实例字段),而另一些通常不能(例如局部变量)。对于当前一代 JVM,线程堆栈位于堆外的内存段中,GC 不会移动它们。
但是,这对于“获取变量的地址”是没有实际意义的,因为您不能在 Java 中这样做。(如果可以,那么 GC 负责处理重定位。)
在 c++ 中,地址不会改变。
请注意,在 c++ 中,您可以为类 tyoe 的变量覆盖 & 运算符,因此即使地址不会更改,您可能从 &variable 获得的值也可能会更改(这不是地址更改,但可能会令人困惑)
它不太可能改变,但不要将你的代码基于它不会改变的假设。