¿Cuál es la sobrecarga en la estructura de cadena que causa que sizeof() sea 32?¿Por qué sizeof (string) == 32?
Respuesta
Algunas implementaciones de std::string
guardan secuencias muy pequeñas directamente en la pila en una matriz de tamaño estático char
en lugar de utilizar el almacenamiento de pila dinámica. Esto permite evitar asignaciones de montón para muchos objetos de cadena pequeños y mejora la localidad de referencia.
Además, habrá un miembro std::size_t
para guardar el tamaño de las cadenas y un puntero (potencialmente no utilizado, vea arriba) para el almacenamiento del montón.
Ah. ¿Y por qué fue esto downvoted? –
Parece ser yo, pero no lo hice intencionalmente. ¡Lo siento por eso! – Bill
@Bill: ¡no te preocupes! Ya me pasó a mí también. –
std::string
normalmente contiene un búfer para la "optimización de cadena pequeña" --- si la cadena es menor que el tamaño del búfer, no se requiere asignación de pila.
Donde "normalmente" == "en Windows" ;-) –
Los compiladores de Windows no son los únicos que hacen la optimización de cadena pequeña –
Claro, pero si no está dispuesto a nombrarlos, entonces es difícil juzgar si esto es un comportamiento "típico", o simplemente lo llama por el hecho de que es el comportamiento de una implementación común (y presumiblemente de otros). –
Depende de la biblioteca. No debe confiar en el tamaño de los objetos std::string
porque es probable que cambie en diferentes entornos (obviamente entre diferentes proveedores de bibliotecas estándar, pero también entre diferentes versiones de la misma biblioteca).
Tenga en cuenta que las implementaciones std::string
están escritas por personas que han optimizado para una variedad de casos de uso, lo que generalmente lleva a 2 representaciones internas, una para cadenas cortas (pequeño búfer interno) y otra para cadenas largas (asignación externa buffer). La sobrecarga está asociada a la celebración de ambos dentro de cada objeto std::string
.
Mi conjetura es:
class vector
{
char type;
struct Heap
{
char* start;
char* end;
char* allocatedEnd;
};
struct Stack
{
char size;
char data[27];
}
union
{
Stack stackVersion;
Heap heapVersion;
} version;
};
Pero apuesto a que hay cientos de maneras de hacerlo.
awww ... no cuenta de referencia? ¿Qué pasó con el plegado? –
@ErikAronesty Hubo una fase en la que se intentó el recuento de referencias con 'std :: string', pero se hizo evidente que no era muy eficiente (había varios artículos) y la optimización de cadenas cortas se hizo popular. –
P: ¿Por qué es un perro amarillo? A: No es necesariamente.
El tamaño de un objeto (a?) Std :: string depende de la implementación. Acabo de comprobar MS VC++ 2010. Efectivamente usa 32 bytes para std :: string. Hay una unión de 16 bytes que contiene el texto de la cadena, si cabe, o un puntero para acumular el almacenamiento de cadenas más largas. Si los implementadores hubieran elegido mantener cadenas de 18 bytes en el objeto de cadena en lugar de en el montón, el tamaño sería de 34 bytes. Los otros 16 bytes comprenden una tara, que contiene cosas tales como la longitud de la cadena y la cantidad de memoria asignada actualmente para la cadena.
Una implementación diferente siempre puede asignar memoria desde el montón. Dicha implementación indudablemente requerirá menos memoria para el objeto de cadena.
En g ++ 5.2 (por ejemplo, en g ++ 4.9, es diferente) una cadena se define básicamente como:
class string {
char* bufferp;
size_t length;
union {
char local_buffer[16];
size_t capacity;
};
};
En un equipo ordinario esto añade hasta 32 bytes (8 + 8 + dieciséis).
La definición real es, por supuesto
typedef basic_string<char> string;
pero la idea es la misma.
- 1. sizeof() estructuras desconocidas. ¿Por qué?
- 2. ¿Por qué sizeof (void) == 1?
- 3. ¿Por qué sizeof (int) es diferente de sizeof (int *)?
- 4. por qué no hay sizeof en java
- 5. ¿Por qué sizeof parse struct members?
- 6. ¿por qué sizeof (13.33) tiene 8 bytes?
- 7. ¿Por qué es -1> sizeof (int)?
- 8. ¿Qué hace sizeof?
- 9. ¿Por qué funciona String (null)?
- 10. cadena literal Sizeof
- 11. Operador sizeof C/C++: ¿Por qué sizeof ('a') devuelve valores diferentes?
- 12. sizeof (int) == sizeof (void *)?
- 13. ¿Por qué se considera sizeof a un operador?
- 14. ¿Por qué no puedo usar sizeof() en un #if?
- 15. ¿por qué sizeof ('a') es 4 en C?
- 16. ¿Por qué hay un operador sizeof ... en C++ 0x?
- 17. ¿Por qué sizeof (param_array) es el tamaño del puntero?
- 18. ¿Por qué llamar al operador sizeof con dos argumentos?
- 19. ¿Por qué (y cuándo) necesito usar paréntesis después de sizeof?
- 20. ¿Por qué mi comparación String to String falla?
- 21. Buffer vs String speed: ¿Por qué String es más rápido?
- 22. C++ sizeof con bool
- 23. Sizeof vs STRLEN
- 24. PostMethod setRequestBody (String) obsoleto - ¿por qué?
- 25. ¿Por qué String es una clase?
- 26. ¿Por qué la clase String es definitiva?
- 27. ¿Por qué no hay un String # shift()?
- 28. sizeof flotador (3,0) vs (3.0f)
- 29. ¿Por qué no puedo crear un diccionario <string, dictionary <string, string >>?
- 30. sizeof java object
Si abre el encabezado '' de su plataforma, puede ver exactamente por qué 'std :: string' es ese tamaño. @Queso: 'sizeof' produce el tamaño de un objeto _en bytes_. –
Si sizeof devuelve el número de bits en el puntero, entonces su compilador está roto –
@Queso: sizeof() devuelve bytes, no bits.Un puntero de 32 bytes es una dirección de 256 bits – mkb