Odpowiedź Sebastiana jest dokładna, ale chciałem wiedzieć, dlaczego jest to bezpieczne, więc zagłębiłem się w kod źródłowy Mapy . Wygląda na to delete(k, v), że w wywołaniu do , w zasadzie po prostu ustawia flagę (a także zmienia wartość zliczania) zamiast faktycznie usuwać wartość:
b->tophash[i] = Empty;
(Pusta jest stałą dla wartości 0)
Wydaje się, że mapa faktycznie przydziela określoną liczbę segmentów w zależności od rozmiaru mapy, która rośnie w miarę wykonywania wstawiania w tempie 2^B(z tego kodu źródłowego ):
byte *buckets;
Więc prawie zawsze jest przydzielonych więcej zasobników niż używasz, a kiedy przeglądasz rangemapę, sprawdza tę tophashwartość każdego zasobnika w tym, 2^Baby zobaczyć, czy może ją pominąć.
Podsumowując, element deletewewnątrz a rangejest bezpieczny, ponieważ dane technicznie wciąż tam są, ale kiedy sprawdza tophash, widzi, że może go po prostu pominąć i nie uwzględniać go w żadnej rangewykonywanej operacji. Kod źródłowy zawiera nawet TODO:
To wyjaśnia, dlaczego użycie tej delete(k,v)funkcji w rzeczywistości nie zwalnia pamięci, po prostu usuwa ją z listy zasobników, do których masz dostęp. Jeśli chcesz zwolnić rzeczywistą pamięć, musisz uczynić całą mapę nieosiągalną, aby wkroczyło czyszczenie pamięci. Możesz to zrobić za pomocą linii takiej jak
map = nil