为什么对相同常量的引用在C ++中占用不同的内存空间?

时间:2018-11-21 22:52:52

标签: c++ reference

我是C ++中引用概念的新手,我有一个问题,涉及到引用纯数字常量的内存分配。 (我首先要检查的另一件事是,我怀疑经常遇到的 const引用意味着对const 的引用,但是我不确定。)

这是我的testing on ideone.com

#include <stdio.h>

int main() {

    const int r0 = 123;
    const int &r1 = 123;
    const int &r2 = 123;
    const int &r3 = r2;

    printf("%p\n", (void *)&r0);
    printf("%p\n", (void *)&r1);
    printf("%p\n", (void *)&r2);
    printf("%p\n", (void *)&r3);

    return 0;
}

和结果:

0x7ffee3bd74c4
0x7ffee3bd74c8
0x7ffee3bd74cc
0x7ffee3bd74cc

answer - How does a C++ reference look, memory-wise?很清楚r2r3相同的原因,这取决于编译器。但是我在考虑为什么编译器也不能使r0r1r2都一样,因为它们都具有相同的纯常量值123。 (如果没有错误的搜索,则称为prvalue)

请注意:在该网站上进行搜索后,我发现了最相关的question - but in python。尽管语言不同,但我认为想法应该相同/相似:从链接来看,如果我的程序是用python编写的,那么在内存空间中只有一个123可以节省空间。

我读过的其他答案:

  1. C++ do references occupy memory:此答案表明,如果有必要,则将int &x实施为*(pointer_to_x)
  2. How does a C++ reference look, memory-wise?:此答案表明编译器将尽力节省空间。

3 个答案:

答案 0 :(得分:6)

您的123不是“常量”。而是一个 literal 。文字构成一个表达式,该表达式是一个prvalue(即,一个临时对象,用该文字所给定的值初始化)。当您将该表达式绑定到引用时,该对象的生存期将延长到引用的生存期,但是这里的重点是,每个这样的对象都是一个不同的对象,因此具有不同的地址。

如果愿意,文本字符串“ 123”提供了有关如何创建对象的规则,但它本身并不是对象。您可以重写代码以使其更加明确:

const int & r = int(123);   // temporary of type "int" and value "123"

(在C ++中,没有一个像“常量”这样的东西。有很多东西以一种或另一种方式保持不变,但是它们都需要更详细的考虑。)

答案 1 :(得分:4)

文字不是对象。引用不引用文字。使用文字初始化引用时,将创建一个临时对象,并且该临时对象的生存期将绑定到引用的生存期。

尽管对象(具有一个局部变量,两个临时变量)具有相同的值,但它们是独立且不同的对象。由于它们是分开的,因此它们占用单独的内存位置。该标准规定了这一点,这使得可以根据对象的内存地址来识别和区分对象。

答案 2 :(得分:4)

三个声明语句:

const int &r1 = 123;
const int &r2 = 123;
const int &r3 = r2;

将初始化3个临时对象,它们的生存期扩展到等于其各自变量的范围。现在,有一条语言规则说:

  

任何两个具有重叠生存期的对象(不是位字段)   除非其中一个是   另一个的子对象或为另一个提供存储,或者如果它们是   同一完整对象中不同类型的子对象,以及一个   其中一个是零大小的基数。

由于引用绑定到3个不同的临时对象,因此您无法在重叠的地址上观察到这些对象。

有趣的是,假设规则可能允许程序在同一地址分配所有三个临时对象,但前提是您的编译器和链接器理论上可以证明您的程序永远不会观察到在同一地址分配的这些对象。 。在您的示例中,这是不可行的,因为您打印了对象的地址。