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 range
mapę, sprawdza tę tophash
wartość każdego zasobnika w tym, 2^B
aby zobaczyć, czy może ją pominąć.
Podsumowując, element delete
wewnątrz a range
jest 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 range
wykonywanej 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