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.
One of the C++ features that sets it apart from other languages
... is that you have to do memory allocation manually. But let's leave that aside:
- allocate on the heap when an object has to be long-lived, i.e. must outlive a certain scope, and is expensive or impossible to copy or move,
- allocate on the heap when an object is large (where large might mean several kilobytes if you want to be on the safe side) to prevent stack overflows, even if the object is only needed temporarily,
- allocate on the heap if you're using the pimpl (compiler firewall) idiom,
- allocate variable-sized arrays on the heap,
- allocate on the stack otherwise because it's so much more convenient.
Note that in the second rule, by "large object" I mean something like
char buffer[1024 * 1024]; // 1MB buffer
but not
std::vector<char> buffer(1024 * 1024);
since the second is actually a very small object wrapping a pointer to a heap-allocated buffer.
As for pointer vs. value members:
- use a pointer if you need heap allocation,
- use a pointer if you're sharing structure,
- use a pointer or reference for polymorphism,
- use a reference if you get an object from client code and the client promises to keep it alive,
- use a value in most other cases.
The use of smart pointers is of course recommended where appropriate. Note that you can use a reference in case of heap allocation because you can always delete &ref
, but I wouldn't recommend doing that. References are pointers in disguise with only one difference (a reference can't be null), but they also signal a different intent.
Best Answer