向量的地址代表什么?

时间:2019-11-02 14:53:58

标签: c++ vector memory-address

如果我从一个函数返回一个向量,则为其分配了对象的地址将与该函数中声明的地址具有相同的地址(不将其作为引用返回)。例如:

vector<int> f() {
    vector<int> foo(5);
    cout << &foo << endl;

    return foo;
}

int main() {

    vector<int> bar = f();
    cout << &bar << endl; // == &foo

    return 0;
}

然后,我认为这是由于复制构造函数而发生的,并且&运算符可能会以某种方式重载,从而打印出从foo复制到bar的向量类的特定成员的地址。 但是,如果我更改场景并在类中移动f(),则行为将与我最初预期的一样:&foo!=&bar:

class A {
    vector<int> foo;
public:
    vector<int> f() {
        foo.push_back(10);
        cout << &foo << endl;

        return foo;
    }
};

int main() {
    A a;
    vector<int> bar = a.f();
    cout << &bar << endl; // != &foo

    return 0;
}

你能解释会发生什么吗?

1 个答案:

答案 0 :(得分:2)

  

向量的地址代表什么?

计算机内存可以是字节数组。内存地址是该图形阵列的索引。所有对象(包括矢量)都是相同的。

  

如果我从一个函数返回一个向量,则为其分配了对象的地址将与该函数中声明的地址具有相同的地址(不将其作为引用返回)。

这不是标准所保证的。但是确实有可能。每当使用命名的返回值优化来取消返回值的复制/移动时,都会发生这种情况。

  

然后我认为这是由于...&运算符可能以....

vector运算符的地址未重载。

  

你能解释会发生什么吗?

您返回成员的副本,而不是本地自动变量。在这种情况下,不能使用NRVO。

不管子对象如何,在任何给定时间都不能有多个对象与同一内存重叠。如果两个对象同时存在,则每个对象必须具有不同的地址。另一方面,一旦释放了一个对象的内存,它就可以被另一个对象重用。

在第一个示例中,局部变量的生存期结束,因此它的内存与从返回值初始化的变量的内存重叠没有问题。

在第二个示例中,a的生存期以及因此其成员与bar的生存期重叠,因此它们在内存中不能重叠。