Чтобы сэкономить память (мне нужна карта, которая сортируется по значениям и по ключам), я храню указатели (ну, на самом деле, итераторы, согласно ответу в этом ТА вопросе) наключи sparsepp в std::vector
и сортировку вектора по значениям ключей на карте:
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_
, но похоже, что он сместился (большинство указателей по-прежнему указывают на значения местоположения, а некоторые нет).
Что я здесь не так делаю?Я, конечно, не вставляю / стираю / ... на карту или с карты.
Редактировать: Вот пример Minimal, Complete и Verifiable.
#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();
}