Creación de objetos en la stack / montón?

El siguiente código crea un objeto en la stack:

Object o; 

Al crear un objeto en el montón, podemos usar:

 Object* o; o = new Object(); 

más bien que:

 Object* o = new Object(); 

Cuando dividimos la creación de objetos de montón sobre dos líneas y llamamos al constructor en la segunda línea ( o = new object() ), ¿significa esto en la primera línea ( Object* o ) que el puntero se creó en la stack? Entonces Object o pone el objeto en la stack, mientras que Object* o pone el puntero a un objeto futuro en la stack?

Mi segunda pregunta implica si las dos líneas de código fueron llamadas fuera de una clase. Hace poco leí ( Administración de memoria global en C en astackmiento o stack? ) Que las variables globales no están contenidas en la stack / stack pero en realidad son otra parte de la memoria. Si este es el caso, ¿ Object* o crearía un puntero que se ubicaría en esta otra parte de la memoria y apunta al objeto Heap?

En realidad, ninguna de las afirmaciones dice nada acerca de Heap o Stack:

 Object o; 

crea un objeto con almacenamiento automático , lo que significa que la ubicación de almacenamiento está determinada por el contexto en el que se declara el objeto: si el código está en una función, esta es la stack de llamadas. Pero la línea también podría ser un miembro de la clase o, como habrás notado, fuera de una función / clase.

Para ilustrar por qué esto es diferente:

 struct Foo { Object o; }; Foo* pf = new Foo(); 

Ahora el objeto pf->o se crea en el montón , no en la stack, aunque (o más bien, porque ) tiene almacenamiento automático.

A la inversa,

 Object* p; 

simplemente declara un puntero, nada más. El almacenamiento del puntero es indistinguible de cualquier otro objeto: tiene almacenamiento automático. Además, la expresión de inicialización no tiene ningún efecto en el almacenamiento variable.

A lo que apunta el puntero es una cuestión completamente diferente. Puede ser un objeto alojado en el montón (usando new por ejemplo) o podría apuntar a otro objeto asignado automáticamente. Considerar:

 Object o; Object* p = &o; 

C ++ ofrece tres formas diferentes de crear objetos:

  1. Basado en stack como objetos temporales
  2. Heap basado en el uso de nuevo
  3. Asignación de memoria estática como variables globales y objetos de ámbito de espacio de nombres

Considera tu caso,

 Object* o; o = new Object(); 

y:

 Object* o = new Object(); 

Ambas formas son iguales. Esto significa que una variable de puntero o se crea en la stack (suponga que sus variables no pertenecen a la categoría 3 anterior) y apunta a una memoria en el montón, que contiene el objeto.

Las dos formas son iguales con una excepción: temporalmente, el nuevo (Object *) tiene un valor indefinido cuando la creación y la asignación son independientes. El comstackdor puede combinarlos nuevamente, ya que el puntero indefinido no es particularmente útil. Esto no se relaciona con las variables globales (a menos que la statement sea global, en cuyo caso sigue siendo cierto para ambas formas).

UN)

 Object* o; o = new Object(); 

“ B)

 Object* o = new Object(); 

Creo que A y B no tienen diferencia. En ambos casos, o es un puntero a la clase Objeto. statement new Object () crea un objeto de clase Object desde la memoria del montón. El enunciado de asignación asigna la dirección de la memoria asignada al puntero o.

Una cosa que me gustaría mencionar es que el tamaño de la memoria asignada desde el montón es siempre el tamaño de (Objeto) no el tamaño de (Objeto) + tamaño de (nulo *).

En ambos ejemplos, las variables locales de tipo Object* se asignan en la stack. El comstackdor puede producir el mismo código en ambos fragmentos si no hay forma de que su progtwig detecte una diferencia.

El área de memoria para variables globales es la misma que el área de memoria para variables estáticas, no está en la stack ni en el montón. Puede colocar variables en esa área al declararlas static dentro de la función. La consecuencia de hacerlo es que la instancia se comparte entre invocaciones simultáneas de su función, por lo que debe considerar cuidadosamente la sincronización cuando usa estática.

Aquí hay un enlace a una discusión sobre el diseño de memoria de un progtwig C en ejecución.