Pregunta

int main(void)
{
   std::string foo("foo");
}

Mi entendimiento es que el código anterior utiliza el asignador predeterminada de llamada nueva. Así que, aunque el foo std :: string se asigna en la pila del buffer interno dentro de foo se asigna en el montón.

¿Cómo puedo crear una cadena que se asigna en su totalidad en la pila?

¿Fue útil?

Solución

Yo quería hacer precisamente esto mismo hace poco y encontré el siguiente código iluminando:

stack_container.h de Chronium

Se define un nuevo std::allocator que puede proporcionar asignación basado en la pila para la asignación inicial de almacenamiento para contenedores STL. Acabé encontrar una forma diferente de resolver mi problema particular, por lo que no usamos en realidad el código de mí mismo, pero tal vez será útil para usted. No asegúrese de leer los comentarios en el código relacionadas con el uso y advertencias.

Para aquellos que han cuestionado la utilidad y la cordura de hacer esto, tenga en cuenta:

  • A menudo se sabe a priori que la cadena tiene un tamaño máximo razonable. Por ejemplo, si la cadena se va a almacenar un entero de 32 bits con formato decimal, usted sabe que usted no necesita más de 11 caracteres para hacerlo. No hay necesidad de una cadena que puede crecer de forma dinámica a tamaño ilimitado en ese caso.
  • La asignación de la pila es más rápido en muchos casos que la asignación del montón.
  • Si se crea la cadena y destruyó frecuencia (supongamos que es una variable local en una función de utilidad de uso general), la asignación de la pila en lugar de la pila evitará la rotación de fragmentación que inducen en el asignador montón. Para las aplicaciones que utilizan una gran cantidad de memoria, esto podría ser un elemento de cambio.

Algunas personas han comentado que una cadena que utiliza la asignación basada en la pila no será un std::string como si esto de alguna manera disminuye su utilidad. Es cierto que no se puede utilizar indistintamente los dos, por lo que no será capaz de pasar su stackstring a las funciones que esperan un std::string. Pero (si lo haces bien), usted será capaz de utilizar todas las mismas funciones miembro en su stackstring que se utiliza ahora en std::string, como find_first_of(), append(), etc. begin() y end() seguirá funcionando bien, por lo que será capaz de utilizar muchos de los algoritmos de STL. Está claro que no se std::string en el sentido más estricto, pero aún así será una "cadena" en el sentido práctico, y todavía será bastante útil.

Otros consejos

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 instancia de std::basic_string con un asignador de memoria que utiliza en la pila, pero no habría una std::string. En particular, no se obtendría el polimorfismo en tiempo de ejecución, y no podía dejar pasar los objetos resultantes en las funciones que esperan un std::string.

No se puede. Excepto ...

std::string es una instanciación de

std::basic_string<class CharType, 
                  class Traits=char_traits<CharType>, 
                  class Allocator=allocator<CharType> >

Se puede definir una clase concebible Allocator que utiliza alloca para la gestión de la memoria. Esto sólo funciona si el propio asignador, y los métodos basic_string que invocan directamente o indirectamente, son todos inline. Un objeto creado con este basic_string asignador sería no ser a std::string, pero se comportaría (en su mayoría) se le parezca. Sin embargo, esto sería una buena cantidad de trabajo para los aumentos limitados. Específicamente, el uso de esta clase para devolver valores de una función sería un movimiento de la carrera limitativo.

No tengo idea de ¿Por qué usted o cualquier otra persona quiere hacer esto.

Sospecho que hacer tal cosa sería difícil de hacer, me pregunto por qué quiere hacerlo? Asignar algo enteramente en la pila, el compilador necesita saber en tiempo de compilación lo que el tamaño exacto de la cosa es - en su ejemplo se tendría que conocer no sólo el tamaño de los metadatos std::string, sino también el tamaño de los datos de cadena sí mismo. Esto no es demasiado flexible, es probable que necesite diferentes tipos de cadenas en función del tamaño de los datos de cadena se desean incluir en ella - no es que sería imposible de hacer, sólo tendería a complicar un poco las cosas.

  • std :: string siempre va a administrar es de almacenamiento interno con el nuevo / eliminar.
  • No sé por qué su pregunta contiene aplicación de cadena de glibc . La aplicación de cadena de la biblioteca de C ++ estándar tiene nada que ver con glibc .
  • La única manera de almacenar una cadena en la pila es utilizar una matriz C Char en la pila (como lo describió Shhnap). Pero eso no es probablemente lo que usted quiere de todos modos: -)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top