metodos - string_t c++
¿Cómo asigno una cadena std:: en la pila usando la implementación de la cadena de glibc? (5)
int main(void)
{
std::string foo("foo");
}
Mi entendimiento es que el código anterior usa el asignador predeterminado para llamar nuevo. Entonces, aunque el std :: string foo está asignado en la pila, el búfer interno dentro de foo está asignado en el montón.
¿Cómo puedo crear una cadena que se asigna por completo en la pila?
El problema es que std::basic_string
tiene un parámetro de plantilla para el asignador. Pero std::string
no es una plantilla y no tiene parámetros.
Por lo tanto, en principio, podría usar una std::basic_string
de instancias de std::basic_string
con un asignador que usa la memoria en la pila, pero no sería una std::string
. En particular, no obtendría polimorfismo en tiempo de ejecución, y no podría pasar los objetos resultantes a funciones que esperan una std::string
.
Quería hacer esto solo recientemente y encontré el siguiente código iluminador:
Define un nuevo std::allocator
que puede proporcionar una asignación basada en la pila para la asignación inicial de almacenamiento para contenedores STL. Terminé encontrando una manera diferente de resolver mi problema particular, por lo que no utilicé el código, pero quizás sea útil para usted. Asegúrese de leer los comentarios en el código con respecto al uso y las advertencias.
Para aquellos que han cuestionado la utilidad y la cordura de hacer esto, considere:
- A menudo, usted sabe a priori que su cadena tiene un tamaño máximo razonable. Por ejemplo, si la cadena va a almacenar un entero de 32 bits con formato decimal, usted sabe que no necesita más de 11 caracteres para hacerlo. No hay necesidad de una cadena que pueda crecer dinámicamente a un tamaño ilimitado en ese caso.
- La asignación desde la pila es más rápida en muchos casos que la asignación desde el montón.
- Si la cadena se crea y se destruye con frecuencia (suponga que es una variable local en una función de utilidad comúnmente utilizada), la asignación desde la pila en lugar del montón evitará la rotación de la fragmentación en el asignador del montón. Para aplicaciones que usan mucha memoria, esto podría cambiar el juego.
Algunas personas han comentado que una cadena que utiliza la asignación basada en la pila no será una std::string
como si esto de alguna manera disminuyera su utilidad. Es cierto que no se pueden usar los dos de manera intercambiable, por lo que no podrá pasar su stackstring
de stackstring
a las funciones que esperan una std::string
. Pero (si lo haces bien), podrás usar todas las mismas funciones de miembro en tu stackstring
que usas ahora en std::string
, como find_first_of()
, append()
, etc. begin()
and end()
seguirá funcionando bien, por lo que podrá utilizar muchos de los algoritmos STL. Claro, no será std::string
en el sentido más estricto, pero seguirá siendo una "string" en el sentido práctico, y seguirá siendo bastante útil.
Sospecho que hacer una cosa así sería difícil, me pregunto por qué quieres hacerlo. Para asignar algo completamente en la pila, el compilador necesita saber en el momento de la compilación cuál es el tamaño exacto de la cosa; en su ejemplo, debería saber no solo el tamaño de los metadatos std::string
, sino también el tamaño de la cadena de datos en sí. Esto no es demasiado flexible, probablemente necesitaría diferentes tipos de cadena dependiendo del tamaño de los datos de cadena que desea incluir en ella, no es imposible hacerlo, sino que tiende a complicar las cosas un poco.
Usted no puede Excepto...
std::string
es una instanciación de
std::basic_string<class CharType,
class Traits=char_traits<CharType>,
class Allocator=allocator<CharType> >
alloca podría definir una clase Allocator que use alloca para la gestión de la memoria. Esto solo funcionaría si el Asignador, y los métodos de basic_string
que lo invocan directa o indirectamente, están todos en inline
. Un objeto basic_string
creado con este asignador no sería una std::string
, pero se comportaría (en su mayoría) como si lo fuera. Sin embargo, esto sería una buena cantidad de trabajo para ganancias limitadas. Específicamente, usar esta clase para devolver valores de una función sería un movimiento que limita la carrera.
No tengo idea de por qué usted o alguien más querría hacer esto.
- std :: string siempre gestionará su almacenamiento interno con new / delete.
- No estoy seguro de por qué su pregunta contiene la implementación de cadenas de glibc . La implementación de la cadena de la biblioteca estándar de c ++ no tiene nada que ver con glibc .
- La única manera de almacenar una cadena en la pila es usar una matriz de caracteres C en la pila (como lo que Shhnap describió). Pero eso probablemente no es lo que quieres de todos modos :-)