The following code creates an object on the stack:
Object o;
When creating an object on the heap we can use:
Object* o;
o = new Object();
rather than:
Object* o = new Object();
When we split the heap object-creation over two lines and call the constructor on the second line (o = new object()), does this mean in the first line (Object* o) the pointer was created on the stack? So Object o puts the object on the stack, whereas Object* o puts the pointer to a future object on the stack?
My second question involves if the two lines of code were called outside of a class. I recently read (Global memory management in C in stack or heap?) that global variables are not contained on the stack/heap but actually another part of memory? If this is the case, would Object* o create a pointer which would sit in this other part of the memory and it points to the heap object?
Actually, neither statement says anything about heap or stack. The code
creates one of the following, depending on its context:
This means that the storage location is determined by the context in which the object is defined. In addition, the C++ standard does not talk about stack vs heap storage. Instead, it talks about storage duration, which can be either automatic, dynamic, static or thread-local. However, most implementations implement automatic storage via the call stack, and dynamic storage via the heap.
Local variables, which have automatic storage, are thus created on the stack. Static (and thread-local) objects are generally allocated in their own memory regions, neither on the stack nor on the heap. And member variables are allocated wherever the object they belong to is allocated. They have their containing object’s storage duration.
To illustrate this with an example:
Now where is the object
Foo::o(that is, the subobjectoof an object of classFoo) created? It depends:foo.ohas static storage becausefoohas static storage, and therefore lives neither on the stack nor on the heap.f.ohas automatic storage sincefhas automatic storage (= it lives on the stack).p->ohas dynamic storage since*phas dynamic storage (= it lives on the heap).pf->ois the same object asf.obecausepfpoints tof.In fact, both
pandpfin the above have automatic storage. A pointer’s storage is indistinguishable from any other object’s, it is determined by context. Furthermore, the initialising expression has no effect on the pointer storage.The pointee (= what the pointer points to) is a completely different matter, and could refer to any kind of storage:
*pis dynamic, whereas*pfis automatic.