Różnica między std :: resize (n) a std :: shrink_to_fit w C ++?

11

Natknąłem się na następujące stwierdzenia:

resize(n)- Zmienia rozmiar kontenera, aby zawierał elementy „n”.
shrink_to_fit()- Zmniejsza pojemność pojemnika w celu dopasowania do jego rozmiaru i niszczy wszystkie elementy poza pojemnością.

Czy istnieje jakaś znacząca różnica między tymi funkcjami? wchodzą w wektory w c ++

Sneha Sridharan
źródło
resize modyfikuje rozmiar kontenera, shrink_to_fit nie. W przypadku normalnego użytkowania nie musisz wiedzieć o funkcji shrink_to_fit, jest ona dostępna tylko po to, aby umożliwić programistom ręczne zwiększenie wydajności ich kodu.
NoSenseEtAl
2
Standardowe pojemniki mają rozmiar i pojemność . Rozmiar to bieżąca liczba elementów w kontenerze, a pojemność to ilość przydzielonej pamięci (z grubsza). Zmiana rozmiaru zmienia rozmiar, shrink_to_fitzmienia pojemność.
Jakiś programista koleś
2
Czy rozumiesz różnicę między capacityi size?
Cubic

Odpowiedzi:

12

Wektory mają dwa atrybuty „długości”, które oznaczają różne rzeczy:

  • sizeto liczba użytecznych elementów w wektorze. Jest to liczba przechowywanych rzeczy. Jest to długość koncepcyjna.
  • capacity to ile elementów zmieściłoby się w ilości pamięci, którą wektor aktualnie przydzielił.

capacity >= sizemusi zawsze być prawdą, ale nie ma powodu, aby zawsze byli równi. Na przykład, po usunięciu elementu, zmniejszenie alokacji wymagałoby utworzenia nowego alokacji o jeden segment mniejszego i przeniesienia pozostałej zawartości („alokuj, przenieś, za darmo”).

Podobnie, jeśli capacity == sizedodasz element, wektor może zwiększyć alokację o jeden element (kolejna operacja „alokuj, przenieś, swobodnie”), ale zwykle dodajesz więcej niż jeden element. Jeśli pojemność musi wzrosnąć, wektor zwiększy swoją pojemność o więcej niż jeden element, dzięki czemu można dodać jeszcze kilka elementów przed ponownym przeniesieniem wszystkiego.

Dzięki tej wiedzy możemy odpowiedzieć na twoje pytanie:

  • std::vector<T>::resize()zmienia rozmiar tablicy. Jeśli zmienisz rozmiar na mniejszy niż jego obecny rozmiar, nadmiar obiektów zostanie zniszczony. Jeśli zmienisz jego rozmiar na większy niż jego obecny rozmiar, „nowe” obiekty dodane na końcu zostaną domyślnie zainicjowane.
  • std::vector<T>::shrink_to_fit()prosi o zmianę pojemności w celu dopasowania do bieżącego rozmiaru. (Implementacje mogą, ale nie muszą uwzględniać tego żądania. Mogą zmniejszyć pojemność, ale nie zrównają się z wielkością. Mogą w ogóle nic nie robić.) Jeśli żądanie zostanie spełnione, spowoduje to odrzucenie części lub całości niewykorzystanej części przydział wektora. Zwykle używasz tego, gdy skończysz budować wektor i nigdy nie dodasz do niego innego elementu. (Jeśli wiesz z góry, ile elementów dodasz, lepiej byłoby std::vector<T>::reserve()powiedzieć wektorowi przed dodaniem jakichkolwiek elementów zamiast polegać na shrink_to_fitrobieniu czegokolwiek.)

Więc używasz, resize()aby zmienić, ile rzeczy jest koncepcyjnie w wektorze.

Używasz tego, shrink_to_fit()aby zminimalizować nadmiar miejsca, które wektor wewnętrznie przydzielił, bez zmiany ilości elementów koncepcyjnie w wektorze.

cdhowie
źródło
2
Zauważ, że shrink_to_fitto nie wszystko albo nic. Implementacja może częściowo zmniejszyć wydajność. Rozważmy na przykład implementację, która ogranicza pojemność wektora do potęg dwóch.
François Andrieux
5

shrink_to_fit() - Zmniejsza pojemność pojemnika w celu dopasowania do jego rozmiaru i niszczy wszystkie elementy poza pojemnością.

To jest błędna charakterystyka tego, co się dzieje. Sekretnie, zniszczenie wszystkich elementów poza częścią pojemności nie jest dokładne.

W C ++, gdy pamięć dynamiczna jest używana dla obiektów, istnieją dwa kroki:

  1. Pamięć jest przydzielana dla obiektów.
  2. Obiekty są inicjowane / konstruowane w miejscach pamięci.

Gdy obiekty w dynamicznie przydzielanej pamięci są usuwane, istnieją również dwa kroki, które odzwierciedlają kroki budowy, ale w odwrotnej kolejności:

  1. Zniszczone obiekty w lokalizacjach pamięci (dla typów wbudowanych jest to noop).
  2. Pamięć używana przez obiekty jest zwalniana.

Pamięć przydzielona poza rozmiar kontenera to tylko bufor. Nie przechowują żadnych poprawnie zainicjowanych obiektów. To tylko surowa pamięć. shrink_to_fit()upewnia się, że nie ma dodatkowej pamięci, ale w tych lokalizacjach nie było żadnych obiektów. Dlatego nic nie jest niszczone, tylko pamięć jest zwalniana.

R Sahu
źródło
2

Zgodnie ze standardem C ++ w stosunku do shrink_to_fit

Efekty: shrink_to_fit jest niewiążącym żądaniem zmniejszenia pojemności () do rozmiaru ().

i w stosunku do resize

Efekty: Jeśli sz <size (), kasuje ostatni rozmiar () - sz elementów z sekwencji. W przeciwnym razie do sekwencji dołączane są domyślnie wstawiane elementy sz - size ().

Oczywiste jest, że funkcje pełnią różne funkcje. Ponadto pierwsza funkcja nie ma parametru, a druga funkcja ma nawet dwa parametry. Ta funkcja shrink_to_fitnie zmienia wielkości kontenera, ale może ponownie przydzielić pamięć.

Vlad z Moskwy
źródło