c++ - unordered_map<string, vector<string>> - 当事情被 push_back 时内存位置改变

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

我这里有这段代码。这是一个奇怪的 unordered_map stringvector<string> .为什么旧字符串的内存位置会随着每个 push_back 而改变?到 vector ?

我在 unordered_map<string, vector<int>> 上尝试了同样的事情,并且 int vector 中 int 的内存位置NOT 表现出相同的行为,即每次 push_back 时,较旧的 int 不会更改其内存位置。我最初虽然这是因为 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;
}

最佳答案

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

例如替换

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

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

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

地址不会改变。 live example

关于c++ - unordered_map<string, vector<string>> - 当事情被 push_back 时内存位置改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39804225/

相关文章:

c++ - 将外部模板类与 STL 类一起使用

java - 如何使用模式匹配获取子字符串

c# - 从字符串数组中删除重复字母的字符串

java - 如果 - 字符后面只有空格,则正则表达式匹配失败

c++ - 为什么 std::function 不能接受推导类型作为其模板参数?

c++ - 在模板基类列表中使用类局部类型别名

c++ - 为什么我在使用 nullptr_t 时收到 "parameter set but not used"警告?

使用 -O1 编译时 C++ regex_search 中断

c++ - 如何停止 gSOAP 操作

c++ - 强制 SHBrowseForFolder() 显示所需的目录