Reputation: 9
Every time you put object into std::vector it has to make a copy of that object.
So can I just put pointers instead of objects like that?:
Class *ptr_Class;
Class object;
ptr_Class = &object;
std::vector<Class*> vector;
vector.push_back(ptr_Class);
Or for some reason it is not a good idea?
Upvotes: 0
Views: 122
Reputation: 34581
You can make a vector of pointers, but you have to be aware that the vector will not automatically call delete
on the pointers when it's done with them. If your pointers were allocated with new
, you have to delete
them yourself before removing elements or destroying the vector, or you'll leak memory. It's tricky to make sure this cleanup happens in all cases; in particular, exceptions can cause cleanup code at the end of a function to be skipped.
It's safer to use a vector of smart pointers, which will take care of that cleanup automatically, even in the face of exceptions. In C++11 you can just make a vector of std::unique_ptr<T>
. With older compilers that don't support C++11, you can use std::tr1::shared_ptr<T>
or boost::shared_ptr<T>
instead, though that has some overhead from reference-counting that you don't really need. You can't put C++98's std::auto_ptr
in a vector (which is why it was deprecated and replaced with std::unique_ptr
in C++11).
Also, in C++11 you have some options for avoiding the copy when inserting an object into a vector:
myvector.push_back(std::move(myobject))
to move the object into the vector instead of copying it. This still constructs a new instance within the vector, but it's allowed to take ownership of any resources held by myobject
instead of copying them. The myobject
shouldn't be used afterward, since it no longer holds the data that it used to.myvector.emplace_back(...)
to construct a new object directly into the vector's storage. This is basically a wrapper for your class's constructor, and can be given any set of arguments that are valid to pass to that constructor.Note that if you want your vector to be polymorphic — that is, if you want to be able to store both squares and circles in a vector of shapes — then a storing pointers (preferably smart pointers) is your only option. All items actually stored within a vector must be the same type, so that type has to be something like a base-class pointer.
Upvotes: 1
Reputation: 314
You are not using "new", or allocating memory, so technically you won't have any memory leaks.
However, you have to be careful with scope. For instance, if you have
std::vector<Class*> funcFoo()
{
Class *ptr_Class;
Class object;
ptr_Class = &object;
std::vector<Class*> vector;
vector.push_back(ptr_Class);
return vector;
}
you will end up with a vector of a pointer that pointed to an object in funcFoo. That object will likely be garbage after you leave the function.
I'm assuming that what you want is more like this:
Class *ptr_Class = new Class();
std::vector<Class*> vector;
vector.push_back(ptr_Class);
If this is the case, then you have to remember to deallocate any memory you allocated with new
by calling delete
.
For instance:
for (unsigned int i = 0; i < vector.size(); ++i)
{
delete vector[i];
vector[i] = NULL;
}
Upvotes: 1
Reputation: 60037
Use a vector of smart pointers. in that way you will not get memory leaks.
The method you have described you have to be careful when popping from the list and you need to ensure that the list is empty when you have finished with it.
Upvotes: 3