C++: ¿Cuál es el tamaño de un objeto de una clase vacía?

7 minutos de lectura

C ¿Cual es el tamano de un objeto de una
Ashwin Nanjappa

Me preguntaba cuál podría ser el tamaño de un objeto de una clase vacía. Seguramente podría no ser 0 bytes, ya que debería ser posible hacer referencia y apuntar a él como cualquier otro objeto. Pero, ¿qué tan grande es tal objeto?

Usé este pequeño programa:

#include <iostream>
using namespace std;

class Empty {};

int main()
{
    Empty e;
    cerr << sizeof(e) << endl;
    return 0;
}

El resultado que obtuve en los compiladores Visual C++ y Cygwin-g++ fue 1 byte! Esto me sorprendió un poco ya que esperaba que fuera del tamaño de la palabra de máquina (32 bits o 4 bytes).

alguien puede explicar por qué el tamaño de 1 byte? Por qué no ¿4 bytes? ¿Esto depende del compilador o de la máquina también? Además, ¿alguien puede dar una razón más convincente de por qué un objeto de clase vacío no ser de tamaño 0 bytes?

  • No veo ninguna razón por la que no pueda ser cero. Pero al darle un tamaño, otras cosas son más fáciles en el compilador. Si tiene una matriz de estas cosas, cada elemento necesita una dirección única. Un tamaño de 1 lo hace fácil.

    – Martín York

    7 de marzo de 2009 a las 10:32

  • Puede tener un tamaño cero si es un subobjeto de clase base.

    – Johannes Schaub – litb

    21 de julio de 2012 a las 11:24

C ¿Cual es el tamano de un objeto de una
Sol

citando Preguntas frecuentes sobre el estilo y la técnica de C++ de Bjarne Stroustrup, la razón por la que el tamaño no es cero es “Para garantizar que las direcciones de dos objetos diferentes sean diferentes”. Y el tamaño puede ser 1 porque la alineación no importa aquí, ya que no hay nada que mirar.

  • Bah, ¿qué diablos sabría él sobre C++? 🙂

    – pax diablo

    17 de marzo de 2009 a las 4:37

  • ¿La necesidad de “garantizar que las direcciones de dos objetos diferentes sean diferentes” tiene algo que ver con C++? Quiero decir, ¿por qué no se sintió la necesidad de C?

    – Lazer

    16 de mayo de 2010 a las 5:21

  • @Lazer, porque no hay estructuras vacías en C.

    – aib

    4 de noviembre de 2010 a las 10:16

  • @nurabha Los puntos de este puntero para el objeto. No está almacenado en el objeto. Sin embargo, si hay funciones virtuales, el objeto contiene un puntero a la vtable.

    – bleher

    19/09/2013 a las 17:03

  • @krish_oza: piensas mal. Cuando asigna una variable en la pila, no puede ocupar cero bytes (porque diferentes variables necesitan diferentes direcciones), de ahí el tamaño mínimo de 1. Después de eso, depende del compilador. Del mismo modo con new; cuando se asigna el espacio, otra asignación debe tener una dirección diferente. Y así. No hay necesariamente ningún puntero involucrado en la clase vacía; puede haber punteros a las variables (o referencias, o asignaciones locales/de pila), pero no son de tamaño cero y no son necesariamente de tamaño de puntero.

    –Jonathan Leffler

    28/02/2014 a las 20:35

1647298628 795 C ¿Cual es el tamano de un objeto de una
TrayMan

El estándar establece que la mayoría de los objetos derivados tienen sizeof() >= 1:

A menos que sea un campo de bits (clase.bit), el objeto más derivado tendrá un tamaño distinto de cero y ocupará uno o más bytes de almacenamiento. Los subobjetos de la clase base pueden tener un tamaño cero.
ISO/IEC FDIS 14882:1998(E) objeto de introducción

  • Me parece difícil de creer. El estándar hace todo lo posible para asegurarse de que las implementaciones tengan las manos libres para hacer un buen trabajo de optimización. Atar las manos del implementador de esa manera no suena como el tipo de cosas que normalmente hace el estándar (podría estar equivocado).

    – Martín York

    7 de marzo de 2009 a las 10:35

  • @eSKay: esto es necesario para que diferentes objetos obtengan direcciones diferentes. No podría tener un mapa de punteros a objetos, por ejemplo, si diferentes instancias tuvieran la misma dirección.

    – Brian Neal

    16 mayo 2010 a las 17:34

1647298628 221 C ¿Cual es el tamano de un objeto de una
paxdiablo

Eso es realmente un detalle de implementación. Una vez, hace mucho tiempo, pensé que podría ser cero bytes o mil bytes, que no tiene nada que ver con la especificación del lenguaje. Pero, después de ver el estándar C++17 (expr.sizeof), sizeof se define como devolver siempre uno o más, pase lo que pase.

El tamaño de una clase más derivada será mayor que cero.

Esto es necesario, entre otras cosas, para permitirle manejar conjuntos de objetos y apuntadores a ellos. Si se permitiera que sus elementos tuvieran tamaño cero, entonces &(array[0]) sería idéntico a &(array[42])que va a causar todo tipo de estragos en sus bucles de procesamiento.

La razón por la que puede no ser una palabra de máquina es que no hay elementos dentro de ella que realmente requieran que se alinee en un límite de palabra (como un número entero). Por ejemplo, si coloca char x; int y; dentro de la clase, mi GCC registra ocho bytes (desde el segundo int deben estar alineados en esa implementación).


Habiendo dicho eso, esa redacción en particular parece haber sido eliminada de C ++ 20, lo que permite al menos el posibilidad de objetos que no pueden ocupar espacio. Sin embargo, se ha añadido el siguiente texto en esa misma sección:

Cuando se aplica a una clase, el resultado es el número de bytes en un objeto de esa clase incluido cualquier relleno necesario para colocar objetos de ese tipo en una matriz.

Dado que las matrices deben poder distinguir entre elementos, eso significaría sizeof tendría que devolver al menos uno, incluso si el objeto en sí técnicamente no ocupara espacio.

Entonces, diferente redacción, pero el mismo efecto general.

  • La razón del “no cero” es que diferentes objetos deben tener diferentes direcciones. Imagine una matriz de objetos de tamaño cero. ¿Cómo lo indexarías? Sin embargo, en algunos casos, el compilador puede optimizar esto (la optimización de la clase base vacía)

    – jalf

    7 de marzo de 2009 a las 11:07

  • @jalf: “¿Cómo lo indexarías?” ¿De la misma manera que lo haría en C (para una matriz de objetos de estructura, por ejemplo)?

    – Lazer

    16 de mayo de 2010 a las 5:24

  • @eSKay: no podrías si tuvieran tamaño 0. Todos estarían en el elemento 0.

    – Brian Neal

    16 mayo 2010 a las 17:35

  • @BrianNeal, que no es problema, ya que no tienen estado para diferenciarse. Los problemas solo llegan cuando consideras los punteros.

    – gha.st

    15 mayo 2013 a las 10:16

  • O tomando el tamaño de dicha matriz para calcular su longitud.

    – gha.st

    15 mayo 2013 a las 10:18

Aunque no se requiere asignar memoria para una clase vacía, pero para crear objetos de clases vacías, el compilador asigna la memoria mínima que se puede asignar, que es 1 byte. De esta manera, el compilador puede distinguir dos objetos de la misma clase vacía de forma única y podrá asignar la dirección del objeto a un puntero del tipo de clase vacía.

1647298628 400 C ¿Cual es el tamano de un objeto de una
Johannes Schaub – litb

Creo que podría ser útil vincular a una respuesta que explique esto también. Se trata boost::compressed_pair por Logan Capaldo.

C ¿Cual es el tamano de un objeto de una
Konstantin Nikitin

Hay una excepción: matrices de longitud 0

#include <iostream>

class CompletlyEmpty {
  char NO_DATA[0];
};

int main(int argc, const char** argv) {
  std::cout << sizeof(CompletlyEmpty) << '\n';
}

1647298629 275 C ¿Cual es el tamano de un objeto de una
Pedro O.

Esto puede ayudarte 🙂
http://bytes.com/topic/c/insights/660463-sizeof-empty-class-structure-1-a

El tamaño de una clase o estructura vacía es 1

La razón por la que esto sucede se reduce a la implementación adecuada del estándar, una de las cosas que dice el estándar C ++ es que “ningún objeto debe tener la misma dirección en la memoria que cualquier otra variable”… ¿Cuál es la forma más fácil de garantizar esto? Asegúrese de que todos los tipos tengan un tamaño distinto de cero. Para lograr esto, el compilador agrega un byte ficticio a las estructuras y clases que no tienen miembros de datos ni funciones virtuales para que tengan un tamaño de 1 en lugar de un tamaño de 0 y luego se garantiza que tienen una dirección de memoria única.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad