动态int *数组作为c++ map的键

dynamic int * arrays as key for C++ map

本文关键字:c++ map 的键 int 数组 动态      更新时间:2023-10-16

我有一些动态int *数组,我想将它们用作unordered_map的键。我有点不清楚我应该如何声明键类型,所以它实际上是整个数组的值。

另外,要为数组释放内存,我是否使用map.clear() ?

的例子:

unordered_map<??, int> frequency;
while (some_condition) {
  int *my_array = new int[size];
  putSomeValuesToArray(my_array);
  frequency[my_array]++;
}
// to deallocate memory for the arrays in frequency?

重要:如果您在STL容器中使用动态分配的对象,那么要释放内存,您需要遍历容器并显式调用delete(或delete[])。

我强烈建议从int*移动到std::vector<int>,您将不再有内存所有权的问题。


为了声明一个键,将类型作为模板参数传递:

std::unordered_map<int*, Foo>
std::unordered_map<std::vector<int>, Foo>

当然,对于unordered_map,您可能需要一个特定的Hash参数,它从您传递的Key派生一个哈希值。

如果你的意思是

int *p = new int[size];

和你想让p作为一个键,那么你更好的选择将是使用std::set()

同样,您不能简单地将其clear();您可能想要delete[]每个元素之前,以避免内存泄漏。如果你不想单独使用delete[],那么你可以使用shared_ptr(或其他智能指针)来为你完成这项工作。

您将无法将int*粘贴为std::map内的键,并且仍然能够"按值"检索元素。这样做的原因是单个int*只提供了一个数组的开始,您还需要结束来计算任何东西(同样的,更像c,长度)。换句话说,int*不是一个数组(动态或非动态);在这里,它是指向序列开头的迭代器。

你可以使用std::pair<int*, int*>,但它应该只用于数据的非拥有'视图'。也就是说,如果您使用std::map<std::pair<int*, int*>, int>手动管理内存,您最终会感到头痛。一种可能是使用智能指针:std::pair<std::unique_ptr<int[]>, int*>。但是正如其他人建议的那样,只使用std::vector,因为它仍然与处理int*的类c接口兼容。另外,const std::pair<std::unique_ptr<int>, int*>仍然允许你乱涂内存,这可能会打乱地图的顺序,最终给你带来麻烦。

使用int*std::unique_ptr<int[]>的最后一个打击是,您需要提供std::map所需的严格弱排序,而std::vector<int>则带有适当的operator<。另一方面,如果您选择std::unordered_map,则需要为两者提供散列。无论如何,使用std::lexicographical_compare(与std::vector比较的语义相同)的简单函子:

struct compare {
    typedef std::pair<std::unique_ptr<int[]>, int*> value_type;
    bool
    operator()(value_type const& lhs, value_type const& rhs) const
    {
        return std::lexicographical_compare(lhs.first.get(), lhs.second
                                           , rhs.first.get(), rhs.second);
    }
};

可以使用std::map<std::pair<std::unique_ptr<int[]>, int*>, int, compare>