Pregunta

En el contexto de C ++ (no es que importe):

class Foo{
    private:
        int x[100];
    public:
        Foo();
}

Lo que aprendí me dice que si creas una instancia de Foo así:

Foo bar = new Foo();

Luego, la matriz x se asigna en el montón, pero si creó una instancia de Foo así:

Foo bar;

Luego se crea en la pila.

No puedo encontrar recursos en línea para confirmar esto.

¿Fue útil?

Solución

Dada una ligera modificación de su ejemplo:

class Foo{
    private:
        int x[100];
        int *y;
    public:
        Foo()
        {
           y = new int[100];
        }
        ~Foo()
        { 
           delete[] y; 
        }

}

Ejemplo 1:

Foo *bar = new Foo();
  • x e y están en el montón:
  • sizeof (Foo *) se crea en la pila.
  • sizeof (int) * 100 * 2 + sizeof (int *) está en el montón

Ejemplo 2:

Foo bar;
  • x está en la pila e y está en el montón
  • sizeof (int) * 100 está en la pila (x) + sizeof (int *)
  • sizeof (int) * 100 está en el montón (y)

Los tamaños reales pueden diferir ligeramente debido a la alineación de clase / estructura dependiendo de su compilador y plataforma.

Otros consejos

Hablando estrictamente, de acuerdo con el estándar, el objeto no necesita existir en una pila o montón. El estándar define 3 tipos de 'duración de almacenamiento', pero no establece exactamente cómo se debe implementar el almacenamiento:

  1. duración del almacenamiento estático
  2. duración de almacenamiento automático
  3. duración del almacenamiento dinámico

La duración del almacenamiento automático se implementa típicamente (casi siempre) usando la pila.

La duración del almacenamiento dinámico generalmente se implementa usando el montón (en última instancia, a través de malloc () ), aunque esto puede ser anulado incluso por el usuario del compilador.

La duración del almacenamiento estático es lo que normalmente se conoce como globales (o almacenamiento estático).

El estándar tiene esto que decir sobre estas cosas (los siguientes son extractos de varios bits de 3.7 - Duración del almacenamiento):

  

Duraciones de almacenamiento estático y automático   están asociados con objetos introducidos   por declaraciones (3.1) e implícitamente   creado por la implementación (12.2).   La duración del almacenamiento dinámico es   asociado con objetos creados con   operador nuevo (5.3.4).

     

...

     

Todos los objetos que no tienen dinámica   la duración del almacenamiento ni son locales tienen   duración del almacenamiento estático El almacenamiento   porque estos objetos durarán por el   duración del programa (3.6.2,   3.6.3).

     

...

     

Objetos locales declarados explícitamente auto   o registrarse o no declarado explícitamente   estático o externo tiene automático   duración del almacenamiento El almacenamiento para   estos objetos duran hasta que el bloque en   que se crean salidas.

     

...

     

Los objetos se pueden crear dinámicamente   durante la ejecución del programa (1.9), usando   expresiones nuevas (5.3.4) y destruidas   utilizando expresiones de eliminación (5.3.5). A C   La implementación de + + proporciona acceso y gestión de almacenamiento dinámico a través de   las funciones de asignación global   operador nuevo y operador nuevo [] y   las funciones de desasignación global   operador eliminar y operador eliminar [].

     

...

     

La biblioteca proporciona valores predeterminados   definiciones para la asignación global   y funciones de desasignación. Algunos   asignación global y desasignación   las funciones son reemplazables (18.4.1)

Y finalmente (con respecto a la matriz en su clase de ejemplo):

  

3.7.4 Duración de los subobjetos [basic.stc.inherit]

     

La duración de almacenamiento de los subobjetos miembros, los subobjetos de la clase base y los elementos de la matriz es la de su completa   objeto (1.8).

Un objeto de tipo Foo toma el tamaño de 100 ints almacenados en secuencia. Si lo crea en la pila, lo obtendrá todo en la pila. Si lo haces con nuevo, estará en el montón como parte del objeto.

Esto es parte de la especificación del lenguaje, no estoy seguro de cuál es su pregunta.

Sí, la matriz de miembros x se creará en el montón si crea el objeto Foo en el montón. Cuando asigna memoria dinámica para Foo , está solicitando memoria de longitud sizeof (Foo) (más posiblemente algo de sobrecarga de memoria, pero ignoremos eso por el momento), que en su código de muestra implica el tamaño de 100 int s. Este tiene ser el caso para la vida útil de los objetos de tipo Foo (y sus datos internos) para cruzar ámbitos.

Si no crea el objeto Foo en el montón, y la matriz interna de Foo no es un puntero al que asigna memoria con nuevo en el constructor de Foo , entonces esa matriz interna se creará en la pila. Nuevamente, este debe ser el caso para que la matriz se limpie automáticamente sin ninguna delete s cuando finalice el alcance. Específicamente,

struct Foo {
    int* y;
    Foo() : y(new int()) { }
    ~Foo() { delete y; }
};

creará y en el montón independientemente de si se creó un objeto Foo en la pila o en el montón.

Te refieres

Foo* bar = new Foo(); 

supongo. Eso se crea en el montón.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top