Operador sizeof

Operador sizeof
Información sobre la plantilla
Concepto:Este operador informa del tamaño de almacenamiento utilizado por cualquier objeto, sea un tipo básico o derivado

Operador sizeof. El operador sizeof informa del tamaño de almacenamiento utilizado por cualquier objeto, sea un tipo básico o derivado.

Sintaxis

El operador unitario sizeof tiene dos formas posibles de sintaxis:

sizeof expresión-unitaria
sizeof (nombre-de-tipo)

A pesar del aspecto de la segunda forma de sintaxis, se trata de un operador, no de una función. sizeof representa una forma cómoda de obtener información sobre el tamaño de los tipos básicos.

Resultado

Cualquiera que sea la forma de sintaxis empleada, el resultado es una constante entera de tipo size_t, con el espacio de memoria (bytes) usada por el operando. Con algunas excepciones, este tamaño es determinado por el tipo de operando, y para cada tipo, depende de la implementación. Es decir, no está predeterminado por el estándar sino por el compilador utilizado.

Ejemplo

#include <iostream.h>
int main(void) {             // ===============
 long double ld;
 class C { public: float x; float y; } c;
 cout << "Tamaño de ld: " << sizeof ld << endl;
 cout << "Tamaño de C: "  << sizeof c << endl;
 cout << "Long double = " << sizeof(long double) << " Bytes" <<  endl;
 return 0;
}
Salida:
Tamaño de ld: 10
Tamaño de C: 8
Long double = 10 Bytes

Comentario

Cuando se utiliza con instancias de tipos se usa la primera forma de la sintaxis; tanto si se trata de tipos básicos (caso de ld en el ejemplo), como si son tipos definidos por el usuario (caso de C). Cuando se utiliza con especificadores de tipo básicos, se utiliza la segunda, con paréntesis (caso de long double). El operador sizeof no puede ser sobrecargado. Puede utilizarse sizeof en directivas de preprocesador (esto es específico de C++ Builder).

sizeof con tipos char

Cuando el operando es de tipo char (con o sin signo) el resultado es 1. Por definición, el resultado de sizeof(char) es siempre 1. Una definición bastante curiosa, ya que desde siempre estamos acostumbrados a que 1 Byte == 1 Octeto == 8 bits. Pero el estándar ANSI C++ establece que 1 Byte es el espacio de almacenamiento necesitado por un carácter, con independencia del número de bits que ocupe en la máquina; aunque hay que reconocer que (por el momento que sepamos) en todos los sistemas un carácter ASCII se almacena en un octeto. En todos los demás casos, el operador proporciona el número de bytes reales ocupados por el operando. Dicho en otras palabras: podría existir una implementación en la que el 1 resultado de sizeof(char) no significara un "octeto", sino otro tamaño.

sizeof con matrices

Cuando el operando es una matriz (que no sea un parámetro), puede utilizarse cualquiera de las dos sintaxis, y el resultado es el tamaño total de la matriz. En otras palabras: la etiqueta de la matriz no es considerada un puntero. El operador sizeof no puede utilizarse con matrices dinámicas o externas. Por ejemplo, el código

extern int m1[];          // L.1
extern char m2[5];        // L.2
int main () {
 ...
 cout << "Tamaño de m1: " << sizeof m1 << endl;   // L.5  ERROR!!
 cout << "Tamaño de m2: " << sizeof m2 << endl;   // L.6

produciría un error de compilación en L.5, ya que aunque la declaración de matriz en L.1 sea correcta, el compilador no dispone de suficiente información para obtener el valor solicitado. En cambio, L.6 compila sin dificultad porque gracias a la declaración L.2 dispone de la información pertinente.

sizeof con matrices C

Las denominadas matrices "C" son conocidas también como NTBS ("Null Terminated Character String"), y como constantes de cadena. Por tradición C, se identifican mediante un puntero a su primer carácter. Es decir, por un tipo char*, mientras que el final de cadena se identifica por el carácter nulo. Ejemplo:

char* cadena = "Cadena de caracteres";

En estas matrices no es posible utilizar el operador sizeof para determinar el tamaño del objeto-cadena, ya que la sentencia

std::cout << sizeof cadena;

siempre devolverá el tamaño del puntero. En estos casos es posible utilizar la función strlen() de la Librería Estándar para calcular la longitud (tamaño) de la matriz señalada:

std::cout << ::strlen(cadena);

El resultado no incluye el carácter de fin de cadena, y que para un valor correcto se exige que la cadena no incluya caracteres nulos intermedios.

sizeof con estructura y uniones

Cuando se aplica a estructuras o uniones, el operador sizeof devuelve el total de bytes, incluyendo cualquier relleno o alineación interna de los datos Ejemplo:

#include <iostream.h>
int main(void) {         // ===============
  struct E1 { char c; float f; } e1;
  struct E2 { float f1; float f2; } e2;
  struct E3 { char c; int i; double d; } e3;
  cout << "Tamaño estr. E1: " << sizeof(E1) << endl;
  cout << "Tamaño estr. E2: " << sizeof(E2) << endl;
  cout << "Tamaño estr. E3: " << sizeof(E3) << endl;
}
Salida:
Tamaño estr. E1: 8
Tamaño estr. E2: 8
Tamaño estr. E3: 16

No se puede utilizar el operador sizeof con expresiones de tipo función; tipos incompletos; nombres parentizados (o tipos análogos), ni campos de bits. La imposibilidad de utilizar este operador con funciones, significa que está orientado a obtener el tamaño de objetos-dato, no de los algoritmos para manipulación de los datos.

sizeof con clases

Debida a la especialísimas características de las clases, la utilización del operador sizeof con estos tipos requiere algunas consideraciones especiales. La sintaxis empleada es distinta según se trate de un nombre-de-tipo o una instancia concreta. Ejemplo

class Cl { long double ld; int i; } c;
class C2 { public: float x; float y; };
cout << sizeof(C1);       // L.1:
cout << sizeof c;         // L.2:
cout << sizeof(C2);

size_t

El resultado producido (devuelto) por el operador sizeof es un entero sin signo denominado de forma estándar size_t, y cuya definición, que depende de la implementación, puede encontrarse en la cabecera <cstddef>]. En el caso de MS Visual C++ 6.0 y Borland C++, el tipo de size_t es unsigned int.

Véase también

Fuente