How to free a vector? - c++

In my class I wrote
class Game {
private:
mtm::Dimensions dimensions;
std::vector<Character*> board;
public:
explicit Game(int height, int width):dimensions(height,width), board(height*width){
}
~Game() {}
};
But how should I free my vector, I think it leaks memory if I leave the d'tor empty.

If Game is not the owner it must not free the memory. The owner has to clean up.
If Game is the owner it can delete all elements in the destructor
~Game() {
for (auto &character : board) {
delete character;
}
}
The better way is to use smart pointers and remove the destructor
std::vector<std::unique_ptr<Character>> board;
You should try to follow the rule of 0

Assuming that your Game owns the objects, then your Game destructor would need to free up the memory. Presumably, the Characters are allocated with new. The below will delete all the Characters in the board, then the class variables (like the vector) will automatically be freed afterward.
~Game() {
for ( Character *character : board )
delete character;
}
Unless this is for an exercise with pointers, it's generally recommended not to use bare-pointers, and instead use a smart pointer, such as unique_ptr or shared_ptr.
std::vector<std::shared_ptr<Character>> board;
In this case, there will be no leak, since the Characters will automatically be freed once no one points to them anymore.
Use of shared_ptr vs unique_ptr is dependent on what you're doing.

The vector is a member variable. Member variables, like all sub objects are automatically destroyed when the super object is destroyed. The implicitly generated destructor does the right thing for vector.
Note that the vector contains pointers. If those pointers point to dynamically allocated objects, and are the only pointers to those objects, then those objects would have to be deleted, or else they would leak. If something else owns the pointed objects, then there is nothing that needs to be done in this destructor.
An example where the implicit destructor is correct. I pretend that the member is public for this example:
{
Character c;
Game g;
g.board.push_back(&c);
} // no leaks
Avoid owning bare pointers. Prefer to use RAII containers or smart pointers if you need ownership of dynamic objects.

the vector destructor won't leak memory you should write destructors for the types used in the vector. Also I wouldn't recommend a pointer to something which dosen't destruct itself.
I think what you are looking for are smart pointers.

Related

Define destructor of class X which inherits from a vector of pointers to object Y and has array of pointers to Z

So I'll try to be as clear as possible about this. Say we have the following:
class X : protected vector<objectY*>
{
private:
objectZ** array;
unsigned size;
unsigned capacity;
public:
X():size(0), capacity(0), array(new objectZ*[100]){}
X(const objectX& o); // to be defined later
X& operator=(const X& x); //defined later
~X(){ delete [] array; clear(); } <--- is this correct, or it produces memory leak?
void add(objectZ* o); // used to add objects to array
}
Now let's say we already defined class Y and Z with all the basic stuff we need for the above code to compile. My question is the following:
Is the destructor correct? Does my code have memory leak?
Say I go to main() and I do this:
objectZ* o1 = new objectZ();
objectX* x1 = new objectX();
x1->add(o1);
delete o1; // to avoid memory leak;
return 0; // end of main.
Since I'm mostly adding stuff to objectX's array from main, and most likely using polymorphism, like
objectZ* ok = new objectK(); // where k is derived from Z
x1->add(ok);
how do I define properly the destructor of class X without having memory leaks, and considering it also inherits from a vector of pointers to another objectY, do I need to cycle the vector 1 by 1 element and call delete on it, and clear() at the end or is clear() enough? Do i cycle array and call delete on it's elements too? My thoughts are that since I'm not allocating memory from within class X, I don't need to deallocate it either. I only need to delete [] array, and possibly clear() the inherited vector.
Is the destructor correct? Does my code have memory leak?
Possibly. If X is supposed to take ownership of the objectZ objects in its array, then it needs to free those objects before then freeing the array itself, otherwise they are leaked.
On a side note, your main() example is leaking the x1 object. It is not clear whether you meant to call delete x1 instead of delete o1, or whether x1->add(o1) is supposed to take ownership of o1 or not.
how do I define properly the destructor of class X without having memory leaks
By not doing manual memory management in the first place. Make proper use of smart pointers, std::unique_ptr and std::shared_ptr, and let them handle the memory management for you.
considering it also inherits from a vector of pointers to another objectY, do I need to cycle the vector 1 by 1 element and call delete on it
Quite likely, yes. It really depends on the ownership model that X employs. If X takes ownership of the objectY and objectZ objects, then it is responsible for freeing them. Otherwise, if it does not take ownership, then it is not responsible for freeing them.
and clear() at the end or is clear() enough?
For an array of raw pointers, clear() simply removes the pointers from the array, it does not free the objects being pointed at. An array of smart pointers, on the other hand, will free the objects when the smart pointers are removed from the array.
My thoughts are that since I'm not allocating memory from within class X, I don't need to deallocate it either.
Any object allocated with new must be freed with delete. Whether that needs to happen inside of X or not will depend on X's particular ownership model.

Destructor and smart pointers giving C2541

I'm trying to use some vectors of shared_ptr in my program, but doing so gives me a C2541-error: "delete": objects that are no pointers can't be deleted. I figured out it has something to do with the destructors of my classes (at least with one of them...) so i tried changing them - without success :(
My application contains a class A, which holds two vectors: one of shared_ptrs to objects of class B and of shared_ptrs to objects of class A.
Here are some parts of my code:
//A.cpp
A::~A(void)
{
for(std::vector<BPtr>::iterator it = allBs.begin(); it != allBs.end(); ++it)
{ //loop that deletes all Bs
delete it->get();
}
for(std::vector<APtr>::iterator it = allAs.begin(); it != allAs.end(); ++it)
{ //loop that (should) delete all As (and their As and Bs)
delete it->get();
delete it.operator*;
}
}
//A.h
class A
{
public:
typedef std::shared_ptr<A> APtr;
typedef std::shared_ptr<B> BPtr;
// some more stuff
private:
std::vector<BPtr> allBs;
std::vector<APtr> allAs;
}
I'm getting the error twice: one comes from the line
delete it.operator*;
and the other one is caused inside of memory.h.
I first had an extra recursive function which deleted the tree and was called by the destructor, but after a little thinking I thought that calling "delete" inside the destructor (line "delete it->get();") would do just the same.
You're doing it wrong.
The entire purpose of smart pointers like std::shared_ptr is that you do not have to manually delete what they point at. Indeed, you must not delete it manually. The smart pointer assumes ownership of the pointee—it will delete it itself when applicable. For std::shared_ptr, "when applicable" means "when the last std::shared_ptr pointing to the object is destroyed."
So just remove the destructor altogether, you don't need it. When the vectors are destroyed, they will destroy all of the contained std::shared_ptrs. This will reduce the reference count of the pointees. If any go to zero, they will be deleted automatically (by the shared_ptr destructor).
You don't want to delete a shared_ptr's contents, that's its job. simply reset the smart pointer:
it->reset();
You can and must delete only things created with new. Only these exactly once, nothing else. Deletion can be done either "by hand" or by letting a smart pointer like std::shared_ptr do it for you (which is a very good idea). When using smart pointers, you can (and should) get rid of the new in favor of std::make_shared or std::make_unique.
The same applies to new[] and delete[].
This means that in your destructor there is no room for delete because you never newed anything and have it owned by a raw pointer (which was good).

destructing an object stored in the vector of pointers [duplicate]

This question already has answers here:
Does std::list::remove method call destructor of each removed element?
(6 answers)
Closed 9 years ago.
I have a class that contains pointers, the class inherits nothing
class MyClass
{
public:
MyClass();
~MyClass();
private:
//i have pointers here
};
MyClass::~MyClass()
{
print("destroyed..");
}
Now i have to use this class as a pointer in vector like this:
vector<MyClass*> classes;
Push some classes in here but when i remove an element:
classes.remove(index);
The destructor doesn't get called,and i think that I have a memory leak.
So how do i make it call the destructor
A vector of pointers does nothing to delete the pointers when they get removed or cleared from it. The vector cannot know if the pointers are dynamically allocated or not. It is not it's job to call delete.
It is up to you to call delete on the pointers, if and when it is necessary. There are not enough details in your question to determine whether it is necessary at all (you haven't shown how the objects pointed to are allocated). But since you claim there is a memory leak, this could indicate that they are dynamically allocated. The immediate solution is to call delete:
delete *it;
classes.erase(it); // vector has no remove member function
A safer solution is to store unique ownership smart pointers, such as std::unique_ptr<MyClass>. The standard library also provides smart pointers for shared and weak ownership. See Smart Pointers.
All the above is assuming that you do actually need to store a pointer. In general, it is safer and clearer to store values:
std::vector<MyClass> classes; // but don't call it "classes". A vector stores objects.
That's one of the reasons why you should avoid using std::vector<MyClass*> at first place. There's an ugly memory management connected with it and it won't stay as easy as classes.remove(index);
Basically, for every new a delete must be called and for every new[] a delete[] must be called, no matter whether you use this pointer as a local variable or you put it into the vector:
vector<MyClass*> vec;
vec.push_back(new MyClass()); // <-- object has been created
...
delete classes[index]; // <-- object shall be destructed
// the delete call will automatically invoke the destructor if needed
...
// now you can remove the dangling pointer from the vector
Just note that once the object has been destructed, any (old) reference to this object is invalid and trying to access this object using such reference (dangling pointer) will yield undefined behavior.
Firstly, std::vector has no remove, you probably mean erase.
Secondly, you need to manually call delete on whatever you're removing:
vector<MyClass*> classes;
auto iter = <iterator to index to remove>;
delete *iter;;
classes.erase(iter);
Or, to avoid all this pain, use a std::unique_ptr<MyClass>.
It is unclear who is responsible for managing the lifetime of the objects pointed by the pointers inside classes. Have you pushed newed pointers into it, or have you pushed the addresses of automatic storage objects?
If you have done the former, then you must manually delete the pointer before removing it. Else, if you have done the latter, then you could just leave it as is, just leaving the pointed-to objects destroy themselves as they leave their respective scopes. If you have mixed newed and non-newed pointers, whose possibility isn't that remote as you would think, then you're definitely damned, undefined behavior making demons fly out of your nose.
These kinds of situations involving pointers are very ambiguous, and it is generally recommended not to use pointers at all, and make the std::vector store plain objects, which makes your object lifetime management much simpler and the making the declaration just speak for itself.
vector<MyClass> classes; // Do this instead
You have to manually delete your pointers before your application exit or after your class object is removed from vector.
// Delete all
vector<MyClass*>::iterator it = classes.begin();
while (it != classes.end()) {
delete *it;
it = classes.erase(it);
}
Tip: Never add stack constructed pointers like following:
MyClass m;
classes.push_back(&m);
Edit: As suggested by other member the better solution is:
MyClass m(/* ... */);
vector<MyClass> classes;
classes.push_back(m);
However please note, you have to properly implement the copy constructor especially if your class has pointer data members that were created with new.
Make a temp pointer to hole MyClass* pointer before you remove it from your vector.
vector<MyClass*> classes;
//push some classes in here but
//when i remove an element
MyClass* temp = classes[index];
classes.remove(index);
// call delete temp; if you want to call the destructor thus avoid memory leak.
delete temp;
To avoid memory leak, remember never to loose control of heap object, always keep a a pointer or reference to it before object release.
It seems that you want your vector to be manager of your items.
Take a look at boost::ptr_vector class
its basically a wrapper around std::vector class.
You declare that this vector is the "holder" of these pointers, and if you remove them from this containers you want them to be deleted.
#include <boost/ptr_container/ptr_vector.hpp>
...
boost::ptr_vector<MyClass> myClassContainer;
myClassContainer.push_back(new MyClass());
myClassContainer.clear(); // will call delete on every stored object!

Handling de-allocation of stl containers in destructors

It is the first time I am using STL and I am confused about how should I deallocate the the memory used by these containers. For example:
class X {
private:
map<int, int> a;
public:
X();
//some functions
}
Now let us say I define the constructor as:
X::X() {
for(int i=0; i<10; ++i) {
map[i]=i;
}
}
Now my question is should I write the destructor for this class or the default C++ destructor will take care of deallocating the memory(completely)?
Now consider the modification to above class
class X {
private:
map<int, int*> a;
public:
X();
~X();
//some functions
}
Now let us say I define the constructor as:
X::X() {
for(int i=0; i<10; ++i) {
int *k= new int;
map[i]=k;
}
}
Now I understand that for such a class I need to write a destructor as the the memory allocated by new cannot be destructed by the default destructor of map container(as it calls destructor of objects which in this case is a pointer). So I attempt to write the following destructor:
X::~X {
for(int i=0; i<10; ++i) {
delete(map[i]);
}
//to delete the memory occupied by the map.
}
I do not know how to delete the memory occupied by the map. Although clear function is there but it claims to bring down the size of the container to 0 but not necessarily deallocate the memory underneath. Same is the case with vectors too(and I guess other containers in STL but I have not checked them).
Any help appreciated.
should I write the destructor for this class or the default C++ destructor will take care of deallocating the memory(completely)?
Yes it will. All the standard containers follow the principle of RAII, and manage their own dynamic resources. They will automatically free any memory they allocated when they are destroyed.
I do not know how to delete the memory occupied by the map.
You don't. You must delete something if and only if you created it with new. Most objects have their memory allocated and freed automatically.
The map itself is embedded in the X object being destroyed, so it will be destroyed automatically, and its memory will be freed along with the object's, once the destructor has finished.
Any memory allocated by the map is the responsibility of the map; it will deallocate it in its destructor, which is called automatically.
You are only responsible for deleting the dynamically allocated int objects. Since it is difficult to ensure you delete these correctly, you should always use RAII types (such as smart pointers, or the map itself) to manage memory for you. (For example, you have a memory leak in your constructor if a use of new throws an exception; that's easily fixed by storing objects or smart pointers rather than raw pointers.)
When a STL collection is destroyed, the corresponding destructor of the contained object is called.
This means that if you have
class YourObject {
YourObject() { }
~YourObject() { }
}
map<int, YourObject> data;
Then the destructor of YourObject is called.
On the other hand, if you are storing pointers to object like in
map<int, YourObject*> data
Then the destruct of the pointer is called, which releases the pointer itself but without calling the pointed constructor.
The solution is to use something that can hold your object, like a shared_ptr, that is a special object that will care about calling the holded item object when there are no more references to it.
Example:
map<int, shared_ptr<YourObject>>
If you ignore the type of container you're dealing with an just think of it as a container, you'll notice that anything you put in the container is owned by whomever owns the container. This also means that it's up to the owner to delete that memory. Your approach is sufficient to deallocate the memory that you allocated. Because the map object itself is a stack-allocated object, it's destructor will be called automatically.
Alternatively, a best practice for this type of situation is to use shared_ptr or unique_ptr, rather than a raw pointer. These wrapper classes will deallocate the memory for you, automatically.
map<int shared_ptr<int>> a;
See http://en.cppreference.com/w/cpp/memory
The short answer is that the container will normally take care of deleting its contents when the container itself is destroyed.
It does that by destroying the objects in the container. As such, if you wanted to badly enough, you could create a type that mismanaged its memory by allocating memory (e.g., in its ctor) but doesn't release it properly. That should obviously be fixed by correcting the design of those objects though (e.g., adding a dtor that releases the memory they own). Alternatively, you could get the same effect by just storing a raw pointer.
Likewise, you could create an Allocator that didn't work correctly -- that allocated memory but did nothing when asked to release memory.
In every one of these cases, the real answer is "just don't do that".
If you have to write a destructor (or cctor or op=) it indicates you likely do something wrong. If you do it to deallocate a resource more likely so.
The exception is the RAII handler for resources, that does nothing else.
In regular classes you use proper members and base classes, so your dtor has no work of its own.
STL classes all handle themselves, so having a map you have no obligations. Unless you filled it with dumb pointers to allocated memory or something like that -- where the first observation kicks in.
You second X::X() sample is broken in many ways, if exception is thrown on the 5th new you leak the first 4. And if you want to handle that situatuion by hand you end up with mess of a code.
That is all avoided if you use a proper smart thing, like unique_ptr or shared_ptr instead of int*.

C++ Destructors with Vectors, Pointers,

As far as I know, I should destroy in destructors everything I created with new and close opened filestreams and other streams.
However, I have some doubts about other objects in C++:
std::vector and std::strings: Are they destroyed automatically?
If I have something like
std::vector<myClass*>
of pointers to classes. What happens when the vector destructor is called?
Would it call automatically the destructor of myClass? Or only the vector is destroyed but all the Objects it contains are still existant in the memory?
What happens if I have a pointer to another class inside a class, say:
class A {
ClassB* B;
}
and Class A is destroyed at some point in the code. Will Class B be destroyed too or just the pointer and class B will be still existent somewhere in the memory?
std::vector and std::strings: Are they destroyed automatically?
Yes (assuming member variables are not pointers to std::vector and std::string).
If I have something like std::vector what happens when the vector destructor is called?
Would it call automatically the destructor of myClass? Or only the vector is destroyed but all the Objects it contains are still existant in the memory?
If vector<MyClass> then all objects contained in the vector will be destroyed. If vector<MyClass*> then all objects must be explicitly deleted (assuming the class being destructed owns the objects in the vector). A third alternative is vector of smart pointers, like vector<shared_ptr<MyClass>>, in which case the elements of the vector do not need to be explictly deleted.
What happens if I have a pointer to another class inside a class
The B must be explicitly deleted. Again, a smart pointer could be used to handle the destruction of B.
You only need to worry about for the memory you have created dynamically (When you reserve memory with new.)
For example:
Class Myclass{
private:
char* ptr;
public:
~Myclass() {delete[] ptr;};
}
if they are in automatic storage, yes. You can have std::string* s = new std::string, in which case you have to delete it yourself.
nothing, you need to manually delete memory you own (for memory allocated with new).
if you allocated b with new, you should destroy it in the destructor explicitly.
A good rule of thumb is to use a delete/delete[] for each new/new[] you have in your code.
A better rule of thumb is to use RAII, and use smart pointers instead of raw pointers.
It depends. std::vector and std::string and MyClass all have 1 thing in common - if you declare a variable to be any of those types, then it will be allocated on stack, be local to the current block you're in, and be destructed when that block ends.
E.g.
{
std::vector<std::string> a;
std::string b;
MyClass c;
} //at this point, first c will be destroyed, then b, then all strings in a, then a.
If you get to pointers, you guessed correctly: Only the memory the pointer itself occupies (usually a 4 byte integer) will be automatically freed upon leaving scope. Nothing happens to the memory pointed to unless you explicitly delete it (whether it's in a vector or not). If you have a class that contains pointers to other objects you may have to delete them in the destructor (depending on whether or not that class owns those objects). Note that in C++11 there are pointer classes (called smart pointers) that let you treat pointers in a similar fashion to 'normal' objects:
Ex:
{
std::unique_ptr<std::string> a = make_unique<std::string>("Hello World");
function_that_wants_string_ptr(a.get());
} //here a will call delete on it's internal string ptr and then be destroyed
If I have something like std::vector what happens when the vector destructor is called?
It depends.
If you have a vector of values std::vector <MyClass>, then the destructor of the vector calls the destructor for every instance of MyClass in the vector.
If you have a vector of pointers std::vector <MyClass*>, then you're responsible for deleting the instances of MyClass.
What happens if I have a pointer to another class inside a class
ClassB instance would remain in memory. Possible ways to have ClassA destructor to make the job for you are to make B an instance member or a smart pointer.
std::vector, std::string and as far as I know all other STL containers have automatic destructors. This is the reason why it is often better to use these containers instead of new and delete since you will prevent memory leaks.
Your myClass destructor will only be called if your vector is a vector of myClass objects (std::vector< myClass >) instead of a vector of pointers to myClass objects (std::vector< myClass* >).
In the first case the destructor of std::vector will also call the destructor of myClass for each of its elements; in the second case the destructor of std::vector will call the destructor of myClass*, which means it will free the space taken to store each pointer but will not free the space taken to store the myClass objects themselves.
The Class B objects you point to will not be destroyed, but the space assigned to store its pointer will be freed.
Yes. std::vector and std::stringare automatically when they finish out of scope, calling also the destructor of the objects contained (for std::vector).
As said before, std::vectoris destroyed when it finish out of scope, calling the destructor of the objects contained. But in fact, in this case, the objects contained are the pointers, not the object pointed by the pointers. So you have to delete them manually.
The same as (2). A will be destroyed and so the pointer, but not the class B pointed. You have to provide a destructor for A that delete B.
In C++11 there is a very useful solution: use std::unique_pointer. Can be use only to point a single object and this will be deleted when the pointer goes out of scope (for example when you destroy your std::vector).
http://en.cppreference.com/w/cpp/memory/unique_ptr