Різниця між std :: resize (n) та std :: shrink_to_fit у C ++?


11

Я натрапив на ці твердження:

resize(n)- Змінює розмір контейнера так, щоб він містив 'n' елементів.
shrink_to_fit()- Зменшує ємність контейнера, щоб відповідати його розмірам, і знищує всі елементи понад ємності.

Чи є значна різниця між цими функціями? вони потрапляють під вектори в c ++


розмір змінює розмір контейнера, shrink_to_fit не робить. Для звичайного використання вам не потрібно знати про shrink_to_fit, він доступний лише для того, щоб розробники могли вручну підвищити продуктивність свого коду.
NoSenseEtAl

2
Стандартні контейнери мають розмір і місткість . Розмір - це поточна кількість елементів у контейнері, тоді як ємність - це об'єм пам'яті, що виділяється (приблизно). Змінення розміру змінює розмір, shrink_to_fitзмінює ємність.
Якийсь програміст чувак

2
Ви розумієте різницю між capacityі size?
Кубік

Відповіді:


12

Вектори мають два атрибути "довжини", які означають різні речі:

  • size- кількість корисних елементів у векторі. Це кількість речей, які ви зберегли. Це концептуальна довжина.
  • capacity - скільки елементів би вмістилося в об'єм пам'яті, який вектор виділив.

capacity >= sizeзавжди повинні бути правдивими, але немає причини, щоб вони завжди були рівними. Наприклад, коли ви видаляєте елемент, зменшення розподілу вимагатиме створення нового виділення на одне відро менше і переміщення решти вмісту ("виділити, перемістити, звільнити").

Аналогічно, якщо capacity == sizeі ви додасте елемент, вектор може збільшити розподіл на один елемент (інший операція "виділити, перемістити, вільно"), але зазвичай ви збираєтеся додати більше одного елемента. Якщо ємність потрібно збільшити, вектор збільшить свою ємність більш ніж на один елемент, так що ви можете додати ще кілька елементів, перш ніж потрібно перенести все заново.

Маючи ці знання, ми можемо відповісти на ваше запитання:

  • std::vector<T>::resize()змінює розмір масиву. Якщо змінити його розмір менше, ніж його поточний розмір, надлишки об'єктів знищуються. Якщо ви зміните його розмір більше, ніж його поточний розмір, "нові" об'єкти, додані в кінці, ініціалізуються за замовчуванням.
  • std::vector<T>::shrink_to_fit()просить змінити ємність відповідно до поточного розміру. (Виконавці можуть або не задовольнити цей запит. Вони можуть зменшити ємність, але не зрівняти його з розміром. Вони можуть взагалі нічого не зробити.) Якщо запит буде виконано, це відкине частину або всю невикористану частину виділення вектора. Зазвичай ви користуєтеся цим, коли закінчите створювати вектор, і ніколи не додасте до нього ще один елемент. (Якщо ви заздалегідь знаєте, скільки предметів ви будете додавати, то краще було std::vector<T>::reserve()б розповісти вектору, перш ніж додавати будь-які елементи, а не покладатися на shrink_to_fitте, щоб робити що-небудь.)

Таким чином, ви використовуєте resize()для зміни кількості концептуальних елементів у векторі.

Ви використовуєте shrink_to_fit()для мінімізації надлишкового простору, який вектор виділив всередині, не змінюючи, скільки матеріалу є концептуально у векторі.


2
Зауважте, що shrink_to_fitце не все або нічого. Впровадження може зменшити частково потужність. Наприклад, розглянемо реалізацію, яка обмежує потенціал вектора двома силами.
Франсуа Андріо

5

shrink_to_fit() - Зменшує ємність контейнера, щоб відповідати його розмірам, і знищує всі елементи понад ємності.

Це неправильна характеристика того, що відбувається. Зокрема, руйнування всіх елементів за межами ємності не є точним.

У C ++, коли динамічно використовується пам'ять для об'єктів, є два етапи:

  1. Для об'єктів виділяється пам'ять.
  2. Об'єкти ініціалізуються / будуються в місцях пам'яті.

Коли об’єкти з динамічно розподіленої пам'яті видаляються, є також два етапи, які відображають етапи побудови, але у зворотному порядку:

  1. Об'єкти в місцях пам'яті зруйновані (для вбудованих типів це нооп).
  2. Пам'ять, яка використовується об'єктами, розміщується.

Пам'ять, що виділяється за розміром контейнера, є просто буфером. Вони не містять належних ініціалізованих об'єктів. Це просто сира пам'ять. shrink_to_fit()гарантує, що додаткової пам’яті немає, але в цих місцях не було об’єктів. Значить, нічого не руйнується, лише пам'ять розміщена.


2

Відповідно до стандарту C ++ щодо shrink_to_fit

Ефекти: shrink_to_fit - не обов'язковий запит щодо зменшення ємності () до розміру ().

і відносно resize

Ефекти: Якщо sz <size (), стирає останній розмір () - sz елементи з послідовності. В іншому випадку додає до послідовності елементи, вставлені за замовчуванням, sz - size ().

Очевидно, що функції роблять різні речі. Більше того, перша функція не має жодного параметра, тоді як друга функція має навіть два параметри. Функція shrink_to_fitне змінює розмір контейнера, хоча може перерозподілити пам'ять.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.