c++ - gnu C++ hash_map : erasing a key: defined?

标签 c++ g++ hashmap

考虑以下程序,这是一个试图用一些遗留代码重现问题的最小示例:

#include <iostream>
#include <ext/hash_map>

// Define a hash for std::string class so we can use it as keys
// in hash_map below.
namespace __gnu_cxx {
    template <>
        struct hash<std::string> {
            size_t operator() (const std::string& x) const {
                return hash<const char*>()(x.c_str());
            }
        };
}

// Data class contains a string
class Data {
    public:
        std::string s;
        Data() { s = "foobar"; }
        Data(std::string s_) : s(s_) {}
};

// Map keyed by string.  Values are Data instances
typedef __gnu_cxx::hash_map<std::string, Data> DataMap;

int main()
{
    DataMap m;
    std::string key = "test";

    // I am storing a "Data" instance d, for "key".  d.s is the same as key.
    Data d = Data(key);
    m[key] = d;

    DataMap::iterator it = m.find(key);
    if (it == m.end()) {
        std::cerr << "not there " << std::endl;
        return 1;
    }
    Data *dp = &it->second;
    // Question about the following line.  Is the behavior well-defined?
    m.erase(dp->s);

    return 0;
}

我将类 Data 实例存储在 hash_map 中。我使用 key 搜索特定数据成员,然后使用 m.erase(dp->s) 删除该值。 m.erase(dp->s) 将删除dp 指向的对象。我是否可以在调用 erase() 时使用 dp->s,或者我必须先复制一份然后再 erase() :

std::string key_to_delete = dp->s;
m.erase(key_to_delete);

最佳答案

查看 implementation ,似乎即使在节点(it 指向的对)被删除后,传递给 erase 函数的键仍然被引用。如果 dp 被删除,那么对 dp->s 的引用将变得无效。然而 hash_map 的实现仍在尝试取消引用它。失败。

您需要传递一些保证对 erase 的调用保持有效的内容。

你可以

m.erase(key);

或者您可以使用 find 返回的迭代器来执行删除:

m.erase(it);

关于c++ - gnu C++ hash_map : erasing a key: defined?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18711298/

相关文章:

c++ - 防止解构宏中定义的匿名变量直到范围结束

c++ - 为什么 g++ 在启用 `-fpic` 的情况下不发出与构造函数相关的 noexcept 警告?

C++ - 构造函数被隐式删除,因为默认定义的格式不正确

C++17 std::G++ 中的可选?

java - Java 中的 HashMap 和 Lists 协调

algorithm - 如何为 HashSet/HashMap 实现哈希函数

c++ - 静态局部对象的构造函数究竟是什么时候调用的?

c++ - llvm如何知道一个成员函数指针是否指向了一个虚函数?

Java HashMap put() 奇怪的行为

c++ - 用于自定义分辨率和同步计时的 AMD API 与 NVIDIA NVAPI 的 NDA 版本是什么等效的?