字符串和int对象或左值/右值的内存位置

时间:2014-11-13 22:07:18

标签: c++ memory memory-address lvalue rvalue

我正在Mac OS X上使用GCC编译以下代码:

using namespace std;

int x;

int& getRef () {
    return x;
}

string getName () {
    return "Alex";
}

int main() {
    int a;
    a = 7;

    getRef() = 4;
    cout << x << ", address: " << &getRef() << endl;

    string name = getName();
    cout << getName() << ", address: " << &name << endl;
}

该程序的输出是:

4, address: 0x10617c0d8
Alex, address: 0x7fff59a851b0

我想了解两件事:

  1. 为什么每次运行此程序时这两个变量的值总是存储在相同的地址下?
  2. 为什么string的地址长于int,这是否与getName()是左值相关?

2 个答案:

答案 0 :(得分:1)

您获得相同的地址,因为您在虚拟内存中运行相同的程序。这意味着您总是拥有自己的地址空间,并且没有理由在确定性运行中有不同的行为。

地址始终具有相同的体系结构特定长度。指针的长度没有说明存储在那里的内存。 (否则指针转换会很困难)

此外,0x0001将被截断为0x1

答案 1 :(得分:1)

这两个变量的地址之间看起来差距很大的原因是它们被分配在可执行映像中的不同内存部分中:

  1. 全局变量x在数据部分中分配。

    因此,在整个程序执行过程中,它的地址是不变的。

  2. 在堆栈中分配局部变量name

    函数中局部变量的地址取决于调用函数时执行点的堆栈状态(SP寄存器的值)。

  3. 在您的示例中,每次调用函数main时,堆栈的状态都完全相同。

    但是假设这个变量是在不同的函数中声明的:

    void func1()
    {
        string name = getName();
        cout << getName() << ", address: " << &name << endl;
    }
    

    现在,尝试从不同的堆栈深度调用此函数,您将得到不同的地址:

    void func2()
    {
        func1();
    }
    
    int main()
    {
        func1();
        func2();
        return 0;
    }