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

Memory location of string and int objects or lvalues/rvalues

本文关键字:内存 位置 int 对象 字符串      更新时间:2023-10-16

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

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()是右值有关吗?

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

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

    因此,它的地址在整个程序执行过程中都是恒定的。

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

    函数

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

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

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

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

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

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

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

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

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