¿Por qué no se std :: string :: max_size () == std :: string :: :: asignador max_size ()

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

  •  22-09-2019
  •  | 
  •  

Pregunta

Recientemente me he dado cuenta de que la siguiente afirmación no es cierta std::string s dado.

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

Me parece interesante, por std::string predeterminada utilizará std::allocator<char> que tiene un límite teórico de size_type(-1) (sí sé que estoy asumiendo complemento a 2, pero eso es ajeno a la pregunta real). Sé que las limitaciones prácticas será significativamente menor que este. En una de 32 bits, x86 sistema típico, el núcleo ocupará de 2 GB (quizás 1 GB) del espacio de direcciones dejando un límite superior práctico mucho más pequeño.

De todos modos, GNU libstdc ++ 's std::basic_string<>::max_size() parece devolver el mismo valor independientemente de lo que el asignador se está utilizando dice (algo así como 1073741820).

Así que la pregunta sigue siendo, ¿por qué no acaba de regresar std::basic_string<>::max_size() get_allocator().max_size()? Me parece que este es el límite superior hipotético. Y si la asignación se queda corto, sólo se va a lanzar un std::bad_alloc, ¿por qué no intentarlo?

Esto es más una curiosidad que otra cosa, me preguntaba por qué los dos se definen por separado en al menos esta aplicación.

¿Fue útil?

Solución

Microsoft Connect fue publicado en relación con su pregunta . Microsoft tiene respuesta interesante a ella:

  

Hemos resuelto como por diseño de acuerdo a nuestra interpretación de la norma, que no explica claramente cuál es el propósito previsto para max_size () es. Allocator max_size () se describe como "el valor más grande que significativa se puede pasar a X :: asignar ()" (C ++ 03 20.1.5 [lib.allocator.requirements] / Tabla 32), pero max_size recipiente () es descrito como "size () de la más grande de contenedores posible" (23.1 [lib.container.requirements] / Tabla 65). Nada describe si o cómo max_size recipiente () debe derivarse de asignador max_size (). Nuestra aplicación para muchos años ha derivado max_size recipiente () directamente desde asignador max_size () y luego se usa este valor para los controles de desbordamiento y así sucesivamente. Otras interpretaciones de la norma, como la suya, son posibles, pero no se corrigen de forma inequívoca a nosotros. La redacción de la norma sin duda podría beneficiarse de una aclaración aquí. A menos que y hasta que eso ocurra, hemos decidido dejar nuestra implementación actual sin cambios por dos razones: (1) otros clientes pueden ser en función de nuestro comportamiento actual, y (2) max_size () fundamentalmente no comprar nada. A lo sumo, las cosas que consumen asignadores (como contenedores) podrían utilizar asignador max_size () para predecir cuándo asignar () fallará - sino simplemente llamando a asignar () es una prueba mejor, ya que el asignador decidirá entonces para dar a conocer la memoria o no. Cosas que consumen los contenedores podrían utilizar max_size contenedor () como garantía de la forma de gran tamaño () podría ser, sino una garantía más simple es la gama de size_type.

aquí se podría encontrar Core Edición # 197. El Comité ha examinado la solicitud a mejorar la redacción de la norma, pero fue rechazada.

Así que la respuesta a la pregunta "¿Por qué ..?" Estándar es que no explica claramente cuál es el propósito previsto para max_size () es.

Otros consejos

No estoy del todo seguro, pero por lo que yo sé std::basic_string no se limita en la norma actual para almacenar la cadena en la memoria continua. Por ejemplo, puede almacenarla en varios trozos. Cada uno de tales trozo se limita entonces a std::allocator::max_size() pero la suma puede ser más grande que eso.

También parece ser el caso de contenedores STL. Y después de todo std::basic_string es un contenedor.

aplicación de GCC tiene un comentario de cómo calcular max_size (uno tiene que restar el tamaño del objeto de limpieza interna que se asigna como un solo bloque con la cadena), y luego añade que max_size() devuelve una cuarta parte de eso. No hay una razón dada, por lo que tal vez es sólo un margen de seguridad? (También debe proporcionar una clase de cuerda, que tal vez se podría utilizar para tan grandes cadenas?)

Con VC ++ max_size() devuelve uno menos de allocator.max_size() - probablemente para dar cuenta de la terminación carácter nulo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top