2012-02-03 16 views
7

Duplicar posible:
std::string and its automatic memory resizing¿Cómo se almacenan las cadenas de C++?

Tengo curiosidad, ¿cómo se almacenan en la memoria cuerdas? por ejemplo, cuando hago esto:

string testString = "asd"; 

asigna 4 bytes, ¿verdad? a + s + d + \0.

Pero más tarde, cuando quiero asignar un texto nuevo a esta cadena, funciona, pero no entiendo cómo. Por ejemplo, hago esto:

testString = "123456789" 

Ahora debe tener 10 bytes de longitud. Pero, ¿y si no hubiera espacio para tal cuerda? digamos que los otros quintos + seis bytes desde el comienzo de la cadena son tomados por otros 2 caracteres. ¿Cómo lo maneja la CPU? ¿Encuentra una posición completamente nueva en la memoria donde encaja esa cuerda?

+0

Quizás no sea un duplicado exacto, la pregunta original ya sabía que la memoria se asignó dinámicamente por la cadena, que no estoy seguro de que fuera el caso aquí. De todos modos, no votaré para reabrir. –

Respuesta

12

Esto depende de la implementación, pero la idea general es que la clase de cadena contendrá un puntero a una región de memoria donde se almacenan los contenidos reales de la cadena. Dos implementaciones comunes son el almacenamiento de 3 punteros (inicio de la región asignada y los datos, fin de los datos, fin de la región asignada) o un puntero (inicio de la región y datos asignados) y dos enteros (número de caracteres en la cadena y número asignado bytes).

Cuando se añaden nuevos datos a la cadena, si se ajusta a la región asignada, se escribirá y el tamaño/final del puntero de datos se actualizará en consecuencia. Si los datos no encajan en la región, se creará un nuevo buffer y se copiarán los datos.

También tenga en cuenta que muchas implementaciones tienen optimizaciones para cadenas pequeñas, donde la clase de cadena contiene un pequeño búfer.Si el contenido de la cadena encaja en el búfer, no se asigna memoria dinámicamente y solo se utiliza el búfer local.

+1

Bueno 3 punteros es 24 bytes (en el arco de 64 bits). Esa es una cadena de tamaño razonable si solo escribes sobre los punteros usando su espacio como el buffer. –

+0

gracias, creo que ahora lo entiendo – user1145902

+1

@LokiAstari: Debería agregar una bandera adicional en algún lugar para identificar si la memoria se usa como memoria intermedia o no. Pero es una suposición razonable que es * barato * reutilizar los punteros para una optimización de búfer pequeña. –

2

string es un objeto, no solo una ubicación de memoria. Asigna dinámicamente memoria según sea necesario.

El operador = está sobrecargado; cuando dice testString = "123456789"; se está llamando a un método y se trata del const char * que aprobó.

+0

Si no me equivoco, 'std :: string' no es un objeto. – jrok

+0

, por lo que los caracteres en cadena no tienen que ordenarse en byte de memoria por byte (como matriz normal) pero se pueden almacenar en alguna ubicación aleatoria. – user1145902

+3

@jrok: Parece que está equivocado ... a menos que realmente quiera decir que 'std :: string' es un tipo (instanciación de una plantilla) a partir de la cual se crean instancias de los objetos ... –

2

Se almacena con un tamaño. Si almacena una nueva cadena, opcionalmente desasignará la memoria existente y asignará nueva memoria para hacer frente al cambio de tamaño.

Y no asigna necesariamente 4 bytes la primera vez que le asigna una cadena de 4 bytes. Puede asignar más espacio que eso (no asignará menos).

3

string no es un tipo de datos simple como char *. Es una clase , que tiene detalles de implementación que no son necesariamente visibles.

Entre otras cosas, string incluye un contador para realizar un seguimiento de lo grande que realmente es.

char[] test = "asd";  // allocates exactly 4 bytes 
string testString = "asd"; // who knows? 

testString = "longer";  // allocates more if necessary 

Sugerencia: escribir un programa simple y paso a través de él utilizando un depurador. Examine el string y vea cómo cambian los miembros privados a medida que se cambia el valor.

+0

gracias, lo intentaré – user1145902

Cuestiones relacionadas