Chcę zapisać pamięć RAM podczas konwersji mapy STD ::: Listę STD ::. Dlatego muszę usunąć każdy element pomiędzy. Ale dostaję 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
    }
}

Jak to zrobić?

2
B. A. Sylla 5 czerwiec 2018, 14:14

3 odpowiedzi

Najlepsza odpowiedź

Jak skomentował Yussuf, możesz znaleźć rozwiązanie w https://stackoverflow.com/a/8234813/1142788. Dostosowałem to do mojego przykładu. (Potrzebuje wsparcia 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
}
1
B. A. Sylla 5 czerwiec 2018, 11:48

Jeśli chcesz zapisać pamięć, nie używaj std::map, ani std::list - użyj std::vector; Lub jeszcze lepiej - nie używaj oddzielnych strun, stosować DE-Duplikacja itp.

Powiedział, że i odpowiedzieć na twoje pytanie: Usuwanie elementu z mapy Unieważnia ieratory do mapy - a pętla dystansowa jest faktycznie oparta na iteratorach. Więc - nie możesz usunąć podczas pętli. Użyj differences_map.clear() po pętli. Należy również pamiętać, że indywidualne delety elementów są znacznie droższe niż rozliczanie całej mapy.

Jeśli twoja pamięć jest tak ograniczona, że nie możesz wziąć udziału zarówno pełnej mapy, jak i pełnej listy w tym samym czasie, po prostu używasz niewłaściwych struktur danych - ponieważ tak, jak powiedziałem, obaj są dość marnotrawne. Nadal, jeśli nalegasz, można wielokrotnie wstawić *differences_map.begin() do listy, a następnie usunąć go z mapy (a za każdym razem, gdy ponownie uzyskaj .begin(), po unieważnienia iteratora).

3
einpoklum 5 czerwiec 2018, 13:39

Możesz rozważyć przechowywanie {x0}} s w swoim map, list lub cokolwiek. Następnie możesz je skopiować tanio i łatwo bez konieczności kopiowania bazowych danych. Nadal masz (bardziej lub mniej) semantyki wartości i nie powinna potrzeba ręcznego zarządzania żywotnością obiektów.

0
Paul Sanders 25 czerwiec 2018, 13:05