c++ - smart - solidity español
¿Una std:: string siempre requiere memoria de pila? (4)
Tengo una pregunta simple Quiero saber si std::string
asigna memoria cada vez en C ++.
En mi código, parece que el constructor usará más memoria para construir tst_first_string
que para tst_second_string
:
char* first_string = new char[5];
strcpy(first_string, "test");
std::string tst_first_string(first_string);
std::string tst_second_string("test");
Depende de la implementación y la longitud de la cadena.
La mayoría de las implementaciones principales tienen optimización de cadenas cortas (SSO), donde la cadena se almacena en el objeto de cadena en sí.
Esto está definido por la implementación, pero como ejemplo, la implementación std::basic_string
en Visual C ++ 2015 Update 3 usará una matriz interna si la longitud de la cadena es menor a 16 bytes. Aquí hay una parte muy editada de _String_val
de <xstring>
:
template<class _Val_types>
class _String_val
{
public:
typedef typename _Val_types::value_type value_type;
enum
{ // length of internal buffer, [1, 16]
_BUF_SIZE = 16 / sizeof (value_type) < 1 ? 1
: 16 / sizeof (value_type)
};
value_type *_Myptr()
{ // determine current pointer to buffer for mutable string
return (this->_BUF_SIZE <= _Myres
? _Bx._Ptr
: _Bx._Buf);
}
union _Bxty
{ // storage for small buffer or pointer to larger one
value_type _Buf[_BUF_SIZE];
pointer _Ptr;
} _Bx;
};
Si observa _Myptr()
, notará que _Buf
se usa cuando la longitud es inferior a _BUF_SIZE
y _Ptr
se usa de otra manera.
Huelga decir que no debe confiar en que esto sea cierto para nada más que esta implementación particular de la biblioteca estándar. Es un detalle interno que puede cambiar en cualquier momento.
Los literales de cadena son de solo lectura. Entonces, una posible optimización es que cuando std::string
apunta a un literal, consiste simplemente en un char *
más una bandera para decir que esto es lo que representa. Cuando escribe en él, por supuesto, tendrá que asignar memoria.
Tanto tst_first_string
como tst_second_string
se construirán usando el constructor para const char*
. Dado que el número de caracteres antes del terminador nul es el mismo en ambos casos, imaginamos que la construcción será exactamente idéntica. Dicho esto, el estándar de C ++ es intencionalmente impreciso en cuanto a lo que debe suceder con respecto a la gestión de memoria, por lo que no sabrá con absoluta certeza.
Tenga en cuenta también que muchas implementaciones de std::string
aprovechan una técnica de optimización de cadenas cortas para cadenas pequeñas que hace que todo el objeto se escriba en la memoria con una duración de almacenamiento automática. En su caso, la memoria dinámica no se puede usar en absoluto.
Lo que sí sabemos con certeza es que a partir de C ++ 11, la semántica de escritura de copia en std::string
ya no está permitida, por lo que se crearán dos cadenas distintas.