std :: map to std :: list ведет к SIGSEGV - PullRequest
0 голосов
/ 05 июня 2018

Я хочу сохранить RAM при преобразовании std :: map в std :: list.Поэтому я должен удалить все элементы между ними.Но я получаю SIGSEGV.

template <class U>
auto ConvertFlatSegmentsMapToList(std::map<std::string /* relative_path */, U>& differences_map, std::list<U>& differences_list) -> void {
    for (auto& i:differences_map) {
        differences_list.push_back(i.second);
        // differences_map.erase(i.first);//TODO: SIGSEGV
    }
}

Как это сделать?

Ответы [ 3 ]

0 голосов
/ 05 июня 2018

Как прокомментировал yussuf, решение можно найти по адресу https://stackoverflow.com/a/8234813/1142788. Я адаптировал это к своему примеру.(требуется поддержка c ++ 11)

template <class U>
auto ConvertFlatSegmentsMapToList(std::map<std::string /* relative_path */, U>& differences_map, std::list<U>& differences_list) -> void {
    std::clog << "differences_map: " << differences_map.size() << std::endl;    // e.g. 6
    std::clog << "differences_list: " << differences_list.size() << std::endl;  // e.g. 0

    for (auto i = differences_map.cbegin(); i != differences_map.cend(); i = differences_map.erase(i)) {
        differences_list.push_back(i->second);
    }

    std::clog << "differences_map: " << differences_map.size() << std::endl;    // e.g. 0
    std::clog << "differences_list: " << differences_list.size() << std::endl;  // e.g. 6
}
0 голосов
/ 05 июня 2018

Вы можете рассмотреть вопрос о сохранении std::shared_ptr s в вашем map, list или чем-либо еще.Затем вы можете легко и просто скопировать их без необходимости копировать исходные данные.Вы по-прежнему получаете (более или менее) семантику значений, и вам не нужно вручную управлять временем жизни объекта.

0 голосов
/ 05 июня 2018

Если вы хотите сэкономить память, не используйте std::map и std::list - используйте std::vector;или еще лучше - не используйте отдельные строки, применяйте дедупликацию и т.д.- и цикл дальнего действия на самом деле основан на итераторах.Таким образом, вы не можете удалить во время цикла.Используйте differences_map.clear() после цикла.Вы также должны заметить, что удаление отдельных элементов намного дороже по времени, чем очистка всей карты.

Если ваша память настолько ограничена, что вы не можете взять и полную карту, и полный список нав то же время, вы просто используете неправильные структуры данных - поскольку, как я уже сказал, оба они довольно расточительны.Тем не менее, если вы настаиваете, вы можете многократно вставлять *differences_map.begin() в список, а затем удалять его с карты (и каждый раз снова получать .begin() после аннулирования итератора).

...