【问题标题】:unordered_map<string, vector<string>> - memory location changes when things are push_backunordered_map<string, vector<string>> - 当事物被 push_back 时内存位置改变
【发布时间】:2017-02-09 18:45:55
【问题描述】:

我这里有这段代码。这是 stringvector&lt;string&gt; 的奇怪 unordered_map。为什么旧字符串的内存位置会随着每个push_back 更改为向量?

我在unordered_map&lt;string, vector&lt;int&gt;&gt; 上尝试了同样的事情,并且整数向量中整数的内存位置确实表现出相同的行为,即对于每个 push_back,旧整数确实不改变他们的记忆位置。我最初虽然是因为 int 在内存方面比字符串小,但推回 50 个 int 仍然不会改变内存位置。为什么会有这样的差异?

这是在 MacOS 上编译的,带有 Apple LLVM 版本 7.3.0 (clang-703.0.31) 的 clang 版本。无论我是否使用 c++11 标志编译都会发生这种情况。

#include <unordered_map>
#include <iostream>
#include <vector>

using namespace std;

int main() {
    unordered_map<string, vector<string> > kvStore;
    kvStore["a"] = vector<string>();
    cout << "kvStore mem location: " << &(kvStore) << endl;
    cout << "kvStore[a] mem location: " << &(kvStore["a"]) << endl;

    cout << endl;
    cout << "--1st push_back--" << endl;
    kvStore["a"].push_back("foo");
    cout << "kvStore mem location: " << &(kvStore) << endl;
    cout << "kvStore[a] mem location: " << &(kvStore["a"]) << endl;
    cout << "kvStore[a][0] mem location: " << &(kvStore["a"][0]) << endl;

    cout << endl;
    cout << "--2nd push_back--" << endl;
    kvStore["a"].push_back("bar");
    cout << "kvStore mem location: " << &(kvStore) << endl;
    cout << "kvStore[a] mem location: " << &(kvStore["a"]) << endl;
    cout << "kvStore[a][0] mem location: " << &(kvStore["a"][0]) << endl;
    cout << "kvStore[a][1] mem location: " << &(kvStore["a"][1]) << endl;

    cout << endl;
    cout << "--3rd push_back--" << endl;
    kvStore["a"].push_back("foobar");
    cout << "kvStore mem location: " << &(kvStore) << endl;
    cout << "kvStore[a] mem location: " << &(kvStore["a"]) << endl;
    cout << "kvStore[a][0] mem location: " << &(kvStore["a"][0]) << endl;
    cout << "kvStore[a][1] mem location: " << &(kvStore["a"][1]) << endl;

    return 0;
}

【问题讨论】:

  • 因为vectors 就是这样工作的。如果您push_back 并且需要增加向量的容量,它会(内部)分配一个新数组并将所有元素复制到该新数组中,然后再添加项目。
  • ints 也会发生这种情况,因为也就是说,其他人如何解释,std::vector 是如何工作的。事实上,我在我的机器上用std::vector&lt;int&gt; 尝试了你的代码示例,并得到了不同的内存位置。请提供一个示例,其中std::vector&lt;int&gt; 上的 50 个push_backs 不会导致内容移动。
  • @ChristianHackl 嗯我会再试一次 - 也许vector&lt;int&gt; 的例子是巧合

标签: c++ string c++11 vector unordered-map


【解决方案1】:

在调用push_back 时,如果新的size() > capacity(),则所有迭代器和对vector 元素的引用都将失效。为避免这种情况,请先致电reserve

例如替换

kvStore["a"] = vector<string>();

kvStore["a"].reserve(3);

mapoperator[] 如果键不存在则创建一个零初始化元素,因此显式赋值是多余的)

并且地址不会改变。 live example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-21
    • 2013-12-19
    • 2020-12-03
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-27
    相关资源
    最近更新 更多