变量除了其内容(例如类型、位置)之外,是否还消耗内存

does a variable consume memory in addition to just its content (e.g. type, location)?

本文关键字:之外 位置 是否 内存 类型 变量      更新时间:2023-10-16
很可能

以前有人问过/回答过这个问题,但不确定如何最好地表达它,链接到以前回答的问题会很棒。

如果您定义类似的东西

char myChar = 'a';

我知道这将占用内存中的一个字节(取决于实现并假设没有 unicode 等,实际数字并不重要)。

但我假设编译器/计算机还需要保留一个变量类型、地址(即指针)以及可能更多的表。否则,它将保留内存,但无法对其进行任何操作。因此,每个变量至少消耗了几字节的内存。

这是对所发生情况的正确描述,还是我误解了程序被编译/执行时会发生什么?如果以上是正确的,那么它与编译或执行有关吗?

编译器将跟踪变量的属性 - 它的名称、生存期、类型、作用域等。此信息仅在编译期间存在于内存中。但是,一旦程序被编译并执行,剩下的就是对象本身。运行时没有类型信息(除非你使用 RTTI,那么会有一些,但只是因为你需要它才能让你的程序运行 - 比如 dynamic_cast ing 需要它)。

访问对象的代码中发生的所有事情都已编译为一种形式,该形式将其完全视为单个字节(因为它是一个char)。无论如何,对象所在的地址只能在运行时知道。但是,具有自动存储持续时间的变量(如局部变量)通常仅通过与当前堆栈帧的一些固定偏移量来定位。该偏移量硬烘焙到可执行文件中。

变量

是否包含额外的信息取决于变量的类型和编译器选项。如果使用 RTTI,则会存储额外的信息。如果使用调试信息进行编译,则还会增加额外的开销。对于本机数据类型(如char示例),通常没有开销,除非您具有也可以填充字节的结构。如果定义类,则可能存在与类关联的虚拟表。但是,如果动态分配内存,则通常会有一些开销以及分配的内存。

有时变量甚至可能不存在,因为优化器意识到它不需要存储,并且可以将其包装在寄存器中。

因此,总的来说,您不能依靠计算您使用的变量并将它们的大小相加来计算它所需的内存量,因为不一定存在 1:1: 关系。

可以在编译类型中检测到某些类型,例如在以下代码中:

void foo(char c) {...}

编译时变量 C 的类型很明显。

在继承的情况下,您无法知道编译类型中变量的真实类型,例如:

void draw(Drawable* drawable); // where drawable can be Circle, Line etc.

但是C++编译器可以帮助使用 dynamic_cast 确定可绘制对象的类型。在这种情况下,它使用指向虚拟方法表的指针,与对象相关联来确定实际类型。