堆栈/堆变量的变量/引用名称或类型存储在内存中的位置

Where are the variable/reference names or types stored in memory for stack/heap variables?

本文关键字:变量 内存 位置 存储 引用名 堆栈 类型      更新时间:2023-10-16

我想我理解堆栈和堆之间的主要区别。

在下面的程序中,将在堆上创建一个大小为 n 的对象。在堆栈上创建了一个引用这个到目前为止无名对象的指针 p,它占用 4 个字节(至少在我的系统上)。如果我理解得很好,由于引用不使用额外的内存,因此不会分配进一步的内存(除了堆栈上 main() 返回的 int)。

Class Object;  // n bytes
int main() {
    Object* p = new Object();
    Object& r = *p;
    // ...
}

尽管如此,内存管理还不完全清楚:

1) 名称 p 和 r 存储在哪里?它们都是本地名称,所以我想它们也应该放在堆栈上吗?这不需要额外的内存来存储变量名和它引用的内存部分之间的绑定吗?

2) 指针的类型存储在哪里?指针在堆栈上仅占用 4 个字节,这(我认为)是存储内存地址的确切大小。计算机如何知道可以在该地址找到哪种类型?

3) 与 (2) 类似,堆上的对象需要 n 个字节的存储空间,并且对它的唯一(直接)引用为 0 个字节。此对象的类型存储在哪里,因此当使用 are 时,它知道它是哪种类型?

4)我知道编译的程序也驻留在内存中的某个地方来指导它的执行。这是在堆栈上还是在堆上,还是这仍然是内存的另一部分?

名称 p 和 r 存储在哪里?

它们不是 - 变量名称是静态的,在运行时不可用。编译器知道变量的存储位置,并生成代码以访问该内存位置,而无需任何名称。

它们可能在程序文件的特殊调试部分中可用,以允许调试器显示变量的值。

指针的类型存储在哪里?

它不是 - 类型也是静态的(与多态类类型关联的有限动态类型信息除外,但不是指针类型)。编译器知道该类型,并生成代码以以该类型的正确方式访问存储的值。

此对象的类型存储在哪里?

如果类型

多态的(即,如果它是一个至少具有一个虚函数的类类型),那么将有一些静态数据存储在您无法直接访问的未指定位置来描述该类型。将有足够的数据来支持虚函数调用(通常是指向最终覆盖的指针表)和RTTI(供dynamic_cast使用的继承结构规范,以及通过typeid可用的type_info结构)。

否则,所有类型信息都是静态的。

[编译的程序]是在堆栈上还是堆上,还是这仍然是内存的另一部分?

在典型的计算机上,它位于静态内存(代码文本部分)中,在程序启动时加载。在嵌入式系统上,它可能更永久地位于只读内存中。

由于引用不使用额外的内存,因此不会分配更多的内存

C++ 标准中没有指定如何实现引用,但大多数编译器会像指针一样实现它们,因此在未优化的代码中,可能会有另外 4 个字节(在您的系统上)用于r......

名称 p 和 r 存储在哪里

这是存储的指针的类型?

[ r ] 的类型存储在哪里

它们在运行时存在于编译器本身内部,并且可能存在于一些调试符号信息中,如果您使用 GCC 的 g++ -g 选项,则放入生成的对象/库/程序中以帮助交互式调试,但它们无法通过正常的C++程序语句存储或访问。

我知道编译的程序也驻留在内存中的某个地方来指导它的执行。这是在堆栈上还是在堆上,还是这仍然是内存的另一部分?

编译的程序是一堆二进制数据和机器代码操作码(数字),操作系统知道如何加载并要求CPU解释和执行。 该数据通常不在堆栈或堆上,而是在操作系统安排的"未初始化数据"、"初始化数据"和"代码"段/区域的混合中。

计算机永远不知道 p 和 r。变量名称用于提高高级语言的可读性。例如,您可以通过以下方式获取汇编代码

gcc -S -c code.c

代码中根本没有 p 和 r。