Чи std :: встановлює збереження об'єктів постійно в пам'яті?


16

Як std::setзберігає об'єкти у суміжній пам'яті, якstd::vector ?

Я не зміг знайти це в Інтернеті, cppreference не згадує деталі про розподіл пам'яті. Але я не бачу, чому він не міг би використовувати суміжну пам'ять, звідси і моє запитання.


5
set::insertВимоги до читання : en.cppreference.com/w/cpp/container/set/insert "... Немає ітераторів чи посилань недійсних ....", тому він не може перерозподіляти, коли його потрібно розширювати, як це std::vectorробити.
Річард Криттен

Ефективність: вам потрібно виміряти (залежно від вашої функції хешування) для вашого випадку використання, див .: channel9.msdn.com/Events/Build/2014/2-661 від 45:48
Річард Криттен

4
Дивіться також boost :: flat_set .
Калет

1
Ви маєте на увазі "суміжний", як у ", коли набір повторюється, об'єкти зберігаються у суміжних місцях пам'яті", або як "усі об'єкти зберігаються в одному великому фрагменті пам'яті (але у довільному порядку)"?
Пабло Н

1
Як правило, коли ви опитуєтесь: "контейнер A такий же, як контейнер B", відповідь "ні", інакше був би лише контейнер A (адже яка б мета контейнера B?). Це, звичайно, не стосується адаптерів контейнерів , але std::setце не одна з тих речей, яка тут є ключовою.
Гонки легкості на орбіті

Відповіді:


25

Чи std :: встановлює об’єкти зберігання у суміжній пам'яті, як std :: vector?

Немає гарантій, що це буде зроблено. Також на практиці це не може через вимоги контейнера. Тому ні, він не зберігає об'єкти у суміжній пам'яті.

Я не бачу, чому він не міг використовувати суміжну пам'ять

Посилання на елементи набору повинні залишатися дійсними після вставки до нього, а також стирання (за винятком посилань на стираний елемент). Ця вимога несумісна з суміжною пам'яттю.

Наскільки мені відомо, збалансоване дерево пошуку - це єдина структура даних, яка може реалізовуватися std::set.


Це може вирізати простір для деревних вузлів з великих суміжних шматочків, якщо це саме означає ОП. (Але жодна ітераторська інвалідація не виключає insertкопіювання всіх вузлів у новий більший блок, щоб обмежити його лише одним блоком, у випадку, якщо на місці reallock виходить з ладу, або (типово для C ++), алокатор не підтримує такого перегляду.)
Пітер Корди

15

Це не виключається явно, хоча певні обмеження std::setунеможливлюють використання суміжної пам'яті.

Наприклад, set::insertмає логарифмічну складність, тоді як vector::insertдля переміщення своїх записів потрібна лінійна складність. Також set::insertне визнає недійсним ітератори. Обидві вимоги неможливо реалізувати за допомогою безперервної пам'яті.

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