I'll start from the beginning...
Vector** v = new Vector*[100];
Allocates an array of 100 pointers to objects of type Vector on the heap
It returns one pointer- v - the you can use to keep track of this array of pointers.
Delete this array of 100 points with:
delete[] v;
(Use the delete
operator- delete
for a single allocated object, delete[]
for an array)
Next case (I'm assuming you mean new Vector[100]
:
Vector* v = new Vector[100];
You allocated an array of 100 Vectors on the heap and got a pointer to its start location- v.
Delete this array with:
delete[] v;
Next...
class Vector
{
int x, y, z;
}
Vector* v = new Vector();
This allocates an object of class Vector on the heap and gives you a pointer to keep track of it. Because you allocated the entire object on the heap, x, y, and z are all allocated on the heap.
Delete it with:
delete v;
class Vector2
{
int items[10];
}
Vector2* v2 = new Vector2();
This one is a bit trickier but I'm going to reason it out...
Classes are blueprints. You haven't allocated any memory at all until you instantiate the class somehow, in this case on the heap. Because the class is a blueprint, items
could not have been allocated until you created an object of class Vector2
on the heap. I think we can reasonably infer that items
is thus allocated on the heap.
Delete v2 with:
delete v2;
And finally:
class Vector3
{
int* items;
}
Vector3 v3 = Vector3();
You allocated all of class Vector3 on the stack, the pointer inside of it items
is also allocated thus. Nothing went on the heap, so don't delete it.
Use automatic (stack) allocation whenever the function scope - or the scope of a control block such as a for
, while
, if
etc. inside the function - is a good match for the lifetime the object needs. That way, if the object owns/controls any resources, such as dynamically allocated memory, file handles etc. - they will be freed during the destructor call as that scope is left. (Not at some unpredictable later time when a garbage collector winds up).
Only use new
if there's a clear need, such as:
needing the object to live longer than the function scope,
to hand over ownership to some other code
to have a container of pointers to base classes that you can then process polymorphically (i.e. using virtual dispatch to derived-class function implementations), or
an especially large allocation that would eat up much of the stack (your OS/process will have "negotiated" a limit, usually in the 1-8+ megabyte range)
- if this is the only reason you're using dynamic allocation, and you do want the lifetime of the object tied to a scope in your function, you should use a local
std::unique_ptr<>
to manage the dynamic memory, and ensure it is released no matter how you leave the scope: by return
, throw
, break
etc.. (You may also use a std::unique_ptr<>
data member in a class
/struct
to manage any memory the object owns.)
Mathieu Van Nevel comments below about C++11 move semantics - the relevance is that if you have a small management object on the stack that controls a large amount of dynamically allocated (heap) memory, move semantics grant extra assurances and fine-grained control of when the management object hands over its resources to another management object owned by other code (often the caller, but potentially some other container/register of objects). This handover can avoid data on the heap being copied/duplicated even momentarily. Additionally, elision and return-value-optimisation often allow nominally automatic/stack-hosted variables to be constructed directly in some memory they're eventually being assigned/returned-to, rather than copied there later.
Best Answer
Stack allocation is much faster since all it really does is move the stack pointer. Using memory pools, you can get comparable performance out of heap allocation, but that comes with a slight added complexity and its own headaches.
Also, stack vs. heap is not only a performance consideration; it also tells you a lot about the expected lifetime of objects.