变量超出范围后如何保留矢量值?

时间:2018-10-12 15:59:33

标签: c++ vector

在foo()中为map<int , std::vector<int>> m1分配局部变量向量,希望s1的值一旦超出范围就无法访问。但事实并非如此。看起来矢量中的元素存储在堆内存中,而局部变量s1存储在堆栈中。当s1存储在map中时,它似乎分配了一个新的堆内存并将值复制到其中。我的理解正确吗? 我在foo中打印每个矢量元素的地址,也在map中打印每个矢量元素的地址。

#include <iostream>
#include <map>
#include <set>
#include<vector>
using namespace std;


std::map<int , std::vector<int>> m1;

void foo(){
    vector<int> s1 = { 10, 20, 30, 40 };
    cout << "local var address: " << &s1 << "\n";
    cout << "Element address " << &s1[0] << "  " << &s1[1] << " "
         << &s1[3] << "  " << &s1[4] << "\n";
    m1[1] = s1;
}


int main() {
    foo();

    cout << "\nElement value and address in map:\n";
    for (auto it = m1[1].begin(); it != m1[1].end();it++) {
        cout << *it << " " << &m1[1][*it] << "\n";  
    }

    return 0;
}

output:

local var address: 0x7fff41714400
Element address 0xc07c20  0xc07c24 0xc07c2c  0xc07c30

Element value and address in map:
10 0xc08cc8
20 0xc08cf0
30 0xc08d18
40 0xc08d40

2 个答案:

答案 0 :(得分:5)

执行m1[1] = s1;时,您正在呼叫m1[1]的{​​{3}}。如果您点击该链接,则表示您正在调用第一个实例,cppreference将其描述为:

  

1)复制分配运算符。将内容替换为其他内容的副本

(重点是我的)

因此,您正在查看两个完全不同的向量和两个完全不同的项目集的地址。比较它们没有任何意义。

答案 1 :(得分:1)

std::map<int , std::vector<int>>

具有value_type的{​​{1}}。这意味着存储在地图中的每个项目都包含这样的矢量对象。

它不包含对矢量的引用或指向矢量的指针,它实际上是一个对象。

这意味着,如果在地图外部中创建矢量,并将其分配给地图元素,则必须 对其进行移动或复制。