假设我有一个指向C++中的 int 的指针。
int i = 1;
int* myInt = &i;
在myInt
中,我有内存位置的信息来获取实际的整数值。我想其中的信息myInt
必须存储在内存中。
但是编译器怎么知道myInt
内存在哪里呢?我想它必须将地址保存myInt
在内存中。但是它把最后的信息保存在哪里呢?Memoryinception
?
这更像是一个关于如何管理内存的一般问题。
每个变量都有自己的内存地址,不管它包含什么。因此,当您存储一个指向整数的指针时,您只是存储了一个指向变量数据的地址。这个地址容器也有一个地址。您可以通过制作指向指针的指针并以您满意的方式显示它们来进行实验:
int i = 1;
int* pointer = &i;
cout << "address1:[" << &i << "] address2:[" << &pointer << "]\n";
每个变量都有一个地址。
全局和静态变量相对于“加载器”放置在内存中的整个模块进行寻址。加载器读取“模块重定位表”,其中包含代码中应更正地址的位置,并更正这些位置。谷歌:也定位独立代码。
自动变量(在函数体中声明)相对于激活记录进行寻址。每次调用函数时,都会将激活记录压入堆栈,这是所有自动变量的“结构”。激活记录的地址存储在硬件寄存器中,用于寻址每个变量。
包括指针在内的所有局部变量都存储在堆栈中。编译后的代码使用堆栈指针相对寻址来访问它们。因此,您的第一个变量将位于 0+sp,您的第二个变量位于第一个变量 + sp 的大小等处。
的实际地址i
以及 的实际地址myInt
直接嵌入到机器代码、访问的实际机器命令i
和访问的实际机器命令中myInt
。
这些最终地址不存储在数据存储器中。相反,它们直接嵌入到通过 CPU 的机器命令流中。它们被称为“立即操作数”。CPU 接收这些地址以及实际的机器命令,因此 CPU 不必从数据存储器中的其他位置检索它们。
所以这就是这个看似“无限”的递归停止的方式。这就是它触底的方式。
对于全局变量,确切的地址在编译时就知道了,并直接嵌入到机器命令中。对于局部变量,当前堆栈帧中的地址偏移量在编译时是已知的,并直接嵌入到机器命令中。