Pourquoi ne pas std :: string :: max_size () == std :: string :: allocateur :: max_size ()

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

  •  22-09-2019
  •  | 
  •  

Question

Récemment, je l'ai remarqué que la déclaration suivante n'est pas vrai std::string s donné.

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

Je trouve cela intéressant, par std::string par défaut utilisera std::allocator<char> qui a une limite théorique de size_type(-1) (oui je sais je suppose que le complément de 2, mais c'est sans rapport avec la question réelle). Je sais que les limites pratiques seront beaucoup moins que cela. Sur un 32 bits typique, système x86, le noyau occupera 2 Go (1 Go peut-être) de l'espace d'adressage en laissant une limite supérieure pratique beaucoup plus petite.

Quoi qu'il en soit, GNU libstdc std::basic_string<>::max_size() de ++ semble renvoyer la même valeur quel que soit le allocateur qu'il utilise dit (quelque chose comme 1073741820).

La question reste, pourquoi ne std::basic_string<>::max_size() pas seulement revenir get_allocator().max_size()? Il me semble que ce soit la limite supérieure hypothétique. Et si l'allocation est à court, il vous reste plus qu'à jeter un std::bad_alloc, alors pourquoi ne pas essayer?

Ceci est plus d'une curiosité que toute autre chose, je me demandais pourquoi les deux sont définis séparément dans au moins celui-ci la mise en œuvre.

Était-ce utile?

La solution

Microsoft Connect a été posté bug lié à votre question . Microsoft a réponse intéressante à elle:

  

Nous l'avons résolu que par la conception selon notre interprétation de la norme, qui n'explique pas clairement ce que l'objectif visé pour max_size () est. Allocateur max_size () est décrit comme "la plus grande valeur qui peut utilement être transmis à X :: allouer ()" (C ++ 03 20.1.5 [lib.allocator.requirements] / Tableau 32), mais contenant max_size () est décrit comme "size () du plus grand réservoir possible" (23,1 [lib.container.requirements] / Table 65). Rien ne décrit si ou comment max_size conteneur () doit être dérivé de allocateur max_size (). Notre mise en œuvre depuis de nombreuses années a dérivé contenant max_size () directement à partir allocateur max_size (), puis utilisé cette valeur pour les contrôles de débordement et ainsi de suite. D'autres interprétations de la norme, comme le vôtre, sont possibles, mais ne sont pas sans ambiguïté correcte pour nous. Le libellé de la norme pourrait certainement bénéficier de précisions. À moins que et jusqu'à ce que cela arrive, nous avons décidé de quitter notre implémentation actuelle inchangée pour deux raisons: (1) d'autres clients peuvent être en fonction de notre comportement actuel, et (2) MAX_SIZE () ne fondamentalement pas acheter quoi que ce soit. Tout au plus, les choses qui consomment allocateurs (comme des conteneurs) peuvent utiliser allocateur max_size () pour prédire quand allouer () échouera - mais simplement appeler allouer () est un meilleur test, puisque l'allocateur va alors décider de donner de la mémoire ou non. Les choses qui consomment des conteneurs pourraient utiliser conteneurs max_size () comme une garantie de la façon dont la grande taille () pourrait être, mais une garantie plus simple est la gamme size_type.

De plus vous pourriez trouver de base numéro 197. Le comité a examiné la demande d'améliorer le libellé de la norme, mais il a été refusé.

Donc, la réponse à votre question: « Pourquoi ..? » est que la norme ne précise pas clairement ce que l'objectif visé pour max_size () est.

Autres conseils

Je suis pas entièrement sûr, mais aussi loin que je sache std::basic_string n'est pas limité dans la norme actuelle pour stocker la chaîne en mémoire continue. Par exemple, il peut stocker en plusieurs morceaux. Chacun de ces gros morceau est alors limité à std::allocator::max_size() mais la somme peut être plus grand que cela.

En outre, il semble être le cas avec des conteneurs STL. Et après tout std::basic_string est un conteneur.

La mise en œuvre du CCG a un commentaire comment ils calculent max_size (on doit soustraire la taille de l'objet de l'entretien ménager interne qui est allouée en un seul bloc avec la chaîne), et ajoute que max_size() retourne un quart de cela. Il n'y a pas de raison donnée, donc peut-être il est juste une marge de sécurité? (Il devrait également fournir une classe de corde, ce qui peut-être on pourrait utiliser pour cordes si grand?)

Avec max_size() VC retourne un de moins que allocator.max_size() - sans doute pour tenir compte de caractère nul.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top