【问题标题】:C++ map with pointer as key. Memory management以指针为键的 C++ 映射。内存管理
【发布时间】:2015-02-25 14:38:48
【问题描述】:

我有一个类似 STL 的映射实现,其中指针作为键。正如我注意到的那样,地图不会释放钥匙。因为我无法保留对所有指针的引用,所以我自己无法管理内存。我读了一些关于智能指针的文章,提出了两个问题:

  1. 除了使用 智能指针?
  2. 当键不再存在或被地图中的另一个指针覆盖时,像 Boosts Smart Pointer 这样的智能指针会释放我的内存吗?

感谢您的帮助。

【问题讨论】:

  • 为什么要使用指针作为键?你想做什么?
  • 如果您希望在映射中不再存在键时释放内存(即映射负责其键的内存......),指针是什么?
  • 通常值是你需要删除的东西,而不是键。价值是多少?
  • @NeilKirk 键是一个无符号字符数组,用 malloc 分配。该值只是一个整数。
  • 那很糟糕。使用std::vectorstd::array 和自定义比较器。

标签: c++ pointers boost stdmap


【解决方案1】:

如果您在没有自定义比较器的情况下使用智能指针作为 std::map 中的键,则它不起作用,因为您根本不会用另一个对象替换一个对象,因为指向一个对象的指针不等同于另一个对象并且替换会不会发生。如果您确实使用了比较器,那么它仍然不会自动工作,因为键是一个常量,并且只有在您替换地图中的项目时才会修改值。所以我认为你有 3 种方法来解决你的问题(假设你使用自定义比较器):

  1. 仍然使用std::map,但在替换元素时先删除先前的键/值对并插入新对,不要使用运算符[]或赋值给iterator->second
  2. 仍使用std::map,但将智能指针和数据保留在value 部分并从您的对象中复制密钥。
  3. 使用不同的容器,例如 Boost.Multi-index。您可能不需要多个索引,但此容器允许使用对象的一部分作为键和 replace 方法。

【讨论】:

  • 1.我有很高的性能要求,我认为在地图中寻找密钥并在之后替换会导致问题。 2.copy key from your object是什么意思。 3. 我已经在使用一个名为 b-tree 的库,但它正在实现 STL 接口,我无法更改容器。
  • @aQuip 无论如何,您都必须寻找替换元素的键。但是删除和读取元素肯定是有代价的。然后使用 2 或 3
  • 您能否解释一下使用值对象中的键时我有什么好处。
  • 假设您反对 hast std::string name 并将其用作比较器的键。解决方案 2 是使用 std::string 作为 std::map 的键并将 name 复制到对象插入的键中。对于 Boost.Multiindex name 字段将是关键,并且您不需要显式代码将 name 复制到关键中,因此至少更少冗长的代码和更少的错误可能性。
  • 好吧,这是有道理的,但我的价值只是一个持有价格的整数。密钥是密钥字符串的二进制表示,与价格无关。这就是为什么我不想创建一个带有价格和key 的对象,它只在对象中用于此目的。为什么给 map 一个指向 char 数组位置的指针是个问题?
【解决方案2】:

可能键是指针指向的对象中的某些东西,而不是指针本身。如果是这样,并且您出于某种原因不想使用智能指针,那么当您擦除地图元素时,请删除该对象。并且不要忘记在地图被释放时将它们全部删除。并且不要忘记处理复制构造函数和赋值运算符等。

【讨论】:

    【解决方案3】:
    1. 在 C++11 中,智能指针是唯一的自动内存管理。

    2. 是的,std::shared_ptr 将在删除最后一个对密钥的引用时删除内存。

    您应该使用字符串而不是动态分配的字符数组。字符串是自动管理的内存。将 shared_ptr 与动态分配的字符数组一起使用并不方便。 shared_ptr 可以很好地管理对象。

    【讨论】:

    • 它实际上会调用析构函数,所以你必须确保有一个好的。
    • std::smart_ptr 嗯,什么?你的意思可能是std::shared_ptr
    • 您能否提供一个使用智能指针和动态分配的字符数组的简单示例?
    • @aQuip 具有动态分配的 char 数组的智能指针是指向 std::vector<char> 或只是 std::string 的智能指针
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 2011-06-01
    • 2014-01-26
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多