Std :: set memorizza gli oggetti contigui nella memoria?


16

Fa std::setoggetti archivio in memoria contigua come std::vector?

Non sono stato in grado di trovarlo sul Web, cppreference non menziona i dettagli sull'allocazione della memoria. Ma non riesco a capire perché non possa usare la memoria contigua, quindi la mia domanda.


5
Leggi i set::insertrequisiti: en.cppreference.com/w/cpp/container/set/insert "... Nessun iteratore o riferimento sono invalidati ....", quindi non può riallocare quando deve espandersi come std::vectorfa.
Richard Critten,

Prestazioni: devi misurare (dipende dalla tua funzione di hashing) per il tuo caso d'uso vedi: channel9.msdn.com/Events/Build/2014/2-661 da 45:48
Richard Critten

4
Vedi anche boost :: flat_set .
Caleth

1
Intendi "contiguo" come in "man mano che il set viene ripetuto, gli oggetti vengono archiviati in posizioni di memoria contigue" o come in "tutti gli oggetti sono archiviati in un grosso pezzo di memoria (ma in ordine arbitrario)"?
Pablo H,

1
Generalmente, quando ti ritrovi a chiedere "il contenitore A è uguale al contenitore B", la risposta è "no", altrimenti ci sarebbe solo il contenitore A (perché quale sarebbe lo scopo di avere il contenitore B?). Questo non si applica ovviamente agli adattatori per container , ma std::setnon è una di quelle cose, che è la chiave qui.
Corse di leggerezza in orbita il

Risposte:


25

Std :: set memorizza oggetti nella memoria contigua come std :: vector?

Non è garantito che lo faccia. Anche in pratica, non può a causa dei requisiti del contenitore. Pertanto no, non memorizza oggetti nella memoria contigua.

Non riesco a capire perché non possa usare la memoria contigua

I riferimenti agli elementi dell'insieme devono rimanere validi al momento dell'inserimento e della cancellazione (ad eccezione dei riferimenti all'elemento cancellato). Questo requisito è incompatibile con la memoria contigua.

Per quanto ne so, un albero di ricerca bilanciato è l'unica struttura di dati che può essere implementata std::set.


Potrebbe ricavare spazio per i nodi degli alberi da grossi pezzi contigui, nel caso in cui questo fosse ciò che significava OP. (Ma nessuna invalidazione dell'iteratore esclude la insertcopia di tutti i nodi in un nuovo blocco più grande per limitarlo a un solo blocco, nel caso in cui realloc sul posto fallisca o (tipico per C ++) l'allocatore non supporti tale riallocazione.)
Peter Cordes

15

Non è escluso esplicitamente, sebbene alcuni vincoli std::setrendano impossibile l'uso della memoria contigua.

Ad esempio, set::insertha complessità logaritmica mentre vector::insertrichiede complessità lineare per mescolare le sue voci. Inoltre set::insertnon invalida gli iteratori. Entrambi i requisiti non possono essere realizzati con memoria contigua.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.