Por que não é std :: string :: max_size () == std :: string :: alocator :: max_size ()

StackOverflow https://stackoverflow.com/questions/1592476

  •  22-09-2019
  •  | 
  •  

Pergunta

Recentemente, notei que a seguinte declaração não é verdadeira dada std::string s.

s.max_size() == s.get_allocator().max_size();

Eu acho isso interessante, por padrão std::string usará std::allocator<char> que tem um limite teórico de size_type(-1) (Sim, eu sei que estou assumindo o complemento de 2, mas isso não está relacionado à pergunta real). Eu sei que as limitações práticas serão significativamente menores do que isso. Em um sistema típico de 32 bits, x86, o kernel ocupará 2 GB (talvez 1 GB) do espaço de endereço, deixando um limite superior prático muito menor.

Enfim, GNU libstdc ++ 's std::basic_string<>::max_size() parece retornar o mesmo valor, independentemente do que o alocador está usando diz (algo como 1073741820).

Então a questão permanece, por que não std::basic_string<>::max_size() Apenas retorne get_allocator().max_size()? Parece -me que este é o limite superior hipotético. E se a alocação for curta, ele apenas jogará um std::bad_alloc, então por que não tentar?

Isso é mais uma curiosidade do que qualquer outra coisa, eu estava me perguntando por que os dois são definidos separadamente em pelo menos essa implementação.

Foi útil?

Solução

Dentro Microsoft Connect foi publicado bug relacionado à sua pergunta. A Microsoft tem uma resposta interessante:

Nós o resolvemos como design de acordo com nossa interpretação do padrão, o que não explica claramente qual é o objetivo pretendido para max_size (). O alocador max_size () é descrito como "o maior valor que pode ser significativamente passado para x :: aloce ()" (c ++ 03 20.1.5 [lib.allocator.ReQuirements]/Tabela 32), mas o contêiner max_size () é descrito como "tamanho () do maior contêiner possível" (23.1 [lib.container.Requirements]/Tabela 65). Nada descreve se ou como o contêiner max_size () deve ser derivado do alocador max_size (). Nossa implementação por muitos anos derivou o contêiner max_size () diretamente do alocador max_size () e, em seguida, usou esse valor para verificações de transbordamento e assim por diante. Outras interpretações do padrão, como a sua, são possíveis, mas não são inequivocamente corretas para nós. A redação do padrão certamente poderia se beneficiar do esclarecimento aqui. A menos e até que isso aconteça, decidimos deixar nossa implementação atual inalterada por dois motivos: (1) outros clientes podem depender do nosso comportamento atual e (2) max_size () fundamentalmente não compra nada. No máximo, as coisas que consomem alocadores (como contêineres) podem usar o alocador max_size () para prever quando o alocado () falhará - mas simplesmente chamar alocada () é um teste melhor, pois o alocador decidirá distribuir ou não a memória. Coisas que consomem contêineres poderiam usar o contêiner max_size () como uma garantia de quão grande poderia ser (), mas uma garantia mais simples é o alcance do size_type.

Adicionalmente aqui Você pode encontrar a edição principal #197. O comitê considerou o pedido para melhorar a redação do padrão, mas foi recusado.

Então, a resposta para sua pergunta "Por que ..?" é que o padrão não explica claramente qual é o objetivo pretendido para max_size ().

Outras dicas

Não tenho certeza, mas tanto quanto eu sei std::basic_string não é limitado no padrão atual para armazenar a string na memória contínua. Por exemplo, ele pode armazená -lo em vários pedaços. Cada um desses pedaços é então limitado a std::allocator::max_size() Mas a soma pode ser maior que isso.

Também parece ser o caso dos contêineres STL. E depois de tudo std::basic_string é um contêiner.

A implementação do GCC tem um comentário como eles calculam max_size (É preciso subtrair o tamanho do objeto interno de limpeza que é alocado como um único bloco com a string) e depois adiciona que max_size() Retorna um quarto disso. Não há racionalidade dada, então talvez seja apenas uma margem de segurança? (Ele também deve fornecer uma classe de corda, que talvez se usasse para cordas tão grandes?)

Com VC ++ max_size() retorna um a menos que allocator.max_size() - Provavelmente para explicar o término do caractere nulo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top