为了节省内存(我需要一个既按值又按键排序的映射),我存储了指向以下键的指针(根据this问题的答案,实际上是迭代器) std::vector
中的sparsepp,然后根据地图中的键值对向量进行排序:
size_t i = 0;
sorted_hashtable_pointer_.resize(hashtable_.size());
for (auto it = hashtable_.begin(); it != hashtable_.end(); it++)
{
sorted_hashtable_pointer_[i] = MapKeyPointer(it);
i++;
}
std::sort(sorted_hashtable_pointer_.begin(), sorted_hashtable_pointer_.end(),
[](MapKeyPointer a, MapKeyPointer b) { return *a < *b; });
其中hashtable_
和sorted_hashtable_pointer_
都是类的成员。
这很好用,在排序之后(以相同的方法),我检查指针(迭代器)是否现在指向正确的位置并且它们确实指向了。
但是,当我以后访问存储的指针(迭代器)时,它们不再指向正确的位置。同时,我没有触摸hashtable_
,但看起来已经移动了(大多数指针仍然指向值位置,而有些则没有)。
我在这里做错了什么?我当然不会在地图上插入/删除/...。
编辑:这是一个最小,完整和可验证的示例。
#include <sparsepp/spp.h>
#include <vector>
#include <stdint.h>
#include <algorithm>
#include <iostream>
struct MyHash {
size_t operator()(std::vector<uint8_t> vec) const
{
std::size_t seed = vec.size();
for(auto& i : vec) {
seed ^= i + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
return seed;
}
};
struct MapKeyPointer
{
typedef spp::sparse_hash_map<std::vector<uint8_t>, std::vector<uint32_t>>::iterator iterator;
MapKeyPointer(iterator i) : it(i) {}
MapKeyPointer() {}
const std::vector<uint8_t>& operator*() const { return it->first; }
const std::vector<uint8_t>* operator->() const { return &it->first; }
iterator it;
};
class Test
{
public:
Test() : maps_(10), sorted_(10) {}
void Init()
{
for (uint32_t i = 0; i < 10; i++)
{
maps_[i] = spp::sparse_hash_map<std::vector<uint8_t>, int, MyHash>();
sorted_[i] = std::vector<MapKeyPointer>();
for (uint32_t j = 0; j < 10000; j++)
{
const std::vector<uint8_t> key
{
(uint8_t)(std::rand() % 255),
(uint8_t)(std::rand() % 255),
(uint8_t)(std::rand() % 255),
(uint8_t)(std::rand() % 255),
(uint8_t)(std::rand() % 255),
(uint8_t)(std::rand() % 255)
};
maps_[i][key] = std::rand();
}
}
}
void Sort()
{
for (size_t i = 0; i < 10; i++)
{
sorted_[i].resize(maps_[i].size());
size_t j = 0;
for (auto it = maps_[i].begin(); it != maps_[i].end(); it++)
{
sorted_[i][j] = MapKeyPointer(it);
j++;
}
std::sort(sorted_[i].begin(), sorted_[i].end(),
[](MapKeyPointer a, MapKeyPointer b) { return *a < *b; });
}
}
void Access()
{
for (size_t i = 0; i < 10; i++)
{
for (size_t j = 0; j < sorted_[i].size(); j++)
{
const std::vector<uint8_t> key = *sorted_[i][j];
std::cout << i << " " << j << " " << key.size() << std::endl;
}
}
}
private:
std::vector<spp::sparse_hash_map<std::vector<uint8_t>, int, MyHash>> maps_;
std::vector<std::vector<MapKeyPointer>> sorted_;
};
int main()
{
Test t;
t.Init();
t.Sort();
t.Access();
}