O std :: set armazena objetos contiguamente na memória?

16

Faz std::setarmazenar objetos em memória contígua como std::vector?

Não consegui encontrar isso na web, a cppreference não menciona detalhes sobre alocação de memória. Mas não consigo entender por que ela não pode usar memória contígua, daí a minha pergunta.

mfnx
fonte
5
Leia os set::insertrequisitos: en.cppreference.com/w/cpp/container/set/insert "... Nenhum iterador ou referência é invalidado ...." para que ele não possa ser realocado quando precisa ser expandido std::vector.
Richard Critten
Desempenho: você precisa medir (depende da sua função de hash) para seu caso de uso, consulte: channel9.msdn.com/Events/Build/2014/2-661 de 45:48
Richard Critten 01/01
4
Veja também boost :: flat_set .
Caleth
11
Você quer dizer 'contíguo' como em "enquanto o conjunto é iterado, os objetos são armazenados em locais de memória contíguos" ou como em "todos os objetos são armazenados em um grande pedaço de memória (mas em ordem arbitrária)"?
Pablo H
11
Geralmente, quando você se pergunta "o contêiner A é o mesmo que o contêiner B", a resposta é "não"; caso contrário, haveria apenas o contêiner A (porque qual seria o objetivo de ter o contêiner B?). Isso não se aplica aos adaptadores de contêineres , std::seté claro, mas não é uma dessas coisas, que é a chave aqui.
Lightness Races em órbita em

Respostas:

25

O std :: set armazena objetos na memória contígua como std :: vector?

Não há garantia de que sim. Também na prática, não pode devido aos requisitos do contêiner. Portanto, não, ele não armazena objetos na memória contígua.

Não vejo por que não foi possível usar memória contígua

As referências aos elementos do conjunto devem permanecer válidas após a inserção e apagamento (exceto as referências ao elemento apagado). Este requisito é incompatível com a memória contígua.

Até onde eu sei, uma árvore de pesquisa equilibrada é a única estrutura de dados que pode ser implementada std::set.

eerorika
fonte
Poderia abrir espaço para os nós das árvores a partir de grandes pedaços contíguos, caso fosse o que o OP significava. (Mas nenhuma invalidação do iterador exclui a insertcópia de todos os nós em um novo bloco maior para limitá-lo a apenas um bloco, caso o realloc no local falhe ou (típico para C ++) o alocador não suporte esse realloc.)
Peter Cordes
15

Não é excluído explicitamente, embora certas restrições std::settornem impossível o uso de memória contígua.

Por exemplo, set::insertpossui complexidade logarítmica enquanto vector::insertrequer complexidade linear para embaralhar suas entradas. Também set::insertnão invalida os iteradores. Ambos os requisitos não podem ser cumpridos com memória contígua.

idclev 463035818
fonte