Having a class that is created throw a new keyword and a pointer pointing to it , then calling a method from the class to destroy the class it self, should i have to free the memory from the pointer or not? somthing like that:
.h
#include <list>
#include <iostream>
class Test
{
public:
Test();
~Test();
void destroy();
bool operator==(Test& right){return id == right.id;};
private:
static int count;
std::list<Test*>::size_type id;
static std::list<Test*> instances;
};
.cpp
#include "Test.h"
int Test::count = 0;
std::list<Test*> Test::instances;
Test::Test()
{
instances.push_back(this);
id = count++;
}
Test::~Test()
{
}
void Test::destroy()
{
for(auto t : instances){
if(*t == *this)
{
delete t;
break;
}
}
}
source
Test* n = new Test();
n->destroy();
so my question is the memory pointed to by n is freed up? or should i call delete n
This will work, but why do it this way? Why not just delete n?
This is what is discussed in the comments in case somebody finds this later.
Basically, looks like you are trying to encapsulate Windows' windowing mechanism and want to destroy the window class on WM_DESTROY.
You've got a map that maps from HWND to the class:
map<HWND,CLASS*> instances;
When WM_DESTROY is received, you can do one of two things:
1. destroy function option
instance[hwnd]->destroy();
Inside destroy, you would have something that looks like this:
void CLASS::destroy() {
// assuming hwnd is a member (probably m_hwnd)
instance.erase(hwnd);
// do some cleanup, and then delete the instance
delete this;
}
2. delete option
delete instance[hwnd];
instance.erase(hwnd);
in this case, you have to put all the clean up code into the destructor of the class.
Option 2 is probably more preferable since it doesn't require you to do delete this;, which while technically ok, may appear unattractive to some people.
Related
Let's assume I got an abstract class ("Book" in the example below) and some derived classes ("ElectroniBook","CodingBook" in the example below). I also want to keep a vector of books in a third class ("Library") and some maps to find them. Let's also assume that I need to create the "Library" from somewhere else using the "addBook" method and then assign it in the main.
Since Book is abstract I eventually need to delete the "Book" pointers I created and I want to do it in some destructor. Neverthless, whenever I try to use delete i got this error message
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
and if I try to replace raw pointers with shared_pointers or unique_pointers I immediately get errors at compile time telling me I'm trying to use pointers that have already been deleted. Note that I'm using C++ 11.
Here's some code just for example :
class Book{
public:
Book(string name, int Npages);
virtual ~Book();
virtual void displayBook() = 0;
private:
string _name;
int _Npages;
}
class ElectronicBook : public Book{
public:
ElectronicBook(string name, int Npages);
~ElectronicBook();
void displayBook() { //do something
};
}
class CodingBook : public Book{
public:
CodingBook(string name, int Npages);
~CodingBook();
void displayBook() { // do something else
};
}
class Library{
public :
Library();
~Library(){
// this doesn't work for me
// for(auto & a : _books)
// delete a;
// _books.clear();
//
//for(int i=0;i<_bookmap.size();++i)
// delete bookmap.at(i);
};
void addCodingBook(string name, int Npages){
CodingBook* cb = new CodingBook(name, Npages);
_books.push_back(cb);
_bookmap[name] = cb;
//should I delete anything here?
};
void addEletronicBook(string name, int Npages){
ElectronicBook* eb = new ElectronicBook(name, Npages);
_books.push_back(eb);
_bookmap[name] = eb;
//should I delete anything here?
};
private :
vector<Book*> _books;
map<string, Book*> bookmap;
}
// separeted function
Library createLibrary(){
Library L;
while(...){
//read books from somewhere(file, input or whatever) and
// addElectronicBook(...)
// addCodingBook(...)
}
return L;
}
int main(){
Library myLibrary = createLibrary();
// do something with Library
}
Since I did several times "new" to add Books, I need to delete them. I tried to do it in the Library destructor like I showed but I got the error mentioned before.
If I understand correctly your issue, you are freeing twice the same memory:
// for(auto & a : _books)
// delete a;
// _books.clear();
//
//for(int i=0;i<_bookmap.size();++i)
// delete bookmap.at(i);
Both _books and bookmap contain pointers that are pointing to the same ares of memory and you are freeing them twice.
When working with raw pointers you have to decide who is the owner of the memory, say, for example _books and who has simply access to the memory but is not responsible for the cleanup.
So, you should:
delete only once, so use only one of the two for loops, say for the sake of argument _books
make sure that the other non-owning structures, say bookmap in our example, never, ever access the memory (i.e. de-reference the pointer) after the deletion
Suggestion: put in the vector unique_ptr so the vector is the owner and put raw pointers in the map to signal that the map is not owning. unique_ptr will take care of cleaning up the memory for you. If you want to be sure, add some print statements or put break points in the destructors if you have a debugger.
I've an abstract class called GameState which looks like this,
#ifndef GAMESTATE_H
#define GAMESTATE_H
#include <iostream>
class GameState
{
public:
virtual ~GameState(void) = 0 { std::cout << "~GameState" << std::endl; };
virtual void init (void) = 0;
virtual void update (void) = 0;
virtual void shutdown (void) = 0;
private:
};
#endif
In main.cpp,
// Lv1Stage and Lv2Stage is derived class from GameState class.
GameState* lv1Stage = new Lv1Stage
GameState* lv2Stage = new Lv2Stage
// This adds states to state vector which is in gameStateManager.
gameStateManager.addState(lv1Stage);
gameStateManager.addState(lv2Stage);
while(gameStateManager.getType() != ST_QUIT)
{
gameStateManager.update();
}
When I quit the game(when I get out of the loop), I gotta release memories that I allocated to GameState. So I made a function in GameStateManager, called clean, which looks like this.
void GameStateManager::clean(void)
{
while (!_states.empty())
{
//first, release all memories of each states.
_states.back()->shutdown();
//and then, clear memory of state..
_states.pop_back();
}
_states.clear();
}
The reason that I made this clean function is, I don't want to delete all of game states I add every single time, like,
delete lv1Stage;
delete lv2Stage;
delete lv3Stage;
...
So I put clean() function in destructor of gameStateManager, but it seems not working since I detected memory leak.
But the thing is, when I delete all the states myself like above code, memory leak is not detected. However, it causes unhandled exception (my guess is because _states is null cuz I deleted it manually).
So, in conclusion,
- I used clean function to de-allocate memories of vector components(which is game states) in destructor.
But it seems not working (memory leak)
However, deleting all memories myself is bothering me.
Can you guys give me some solutions or, what am I missing?
Your vector holds GameState* pointers to objects that are allocated with new. They must be freed with delete. So, you need to add that, eg:
_states.back()->shutdown();
delete _states.back(); // <-- add this!
_states.pop_back();
If you are using C++11 or later, you can change your vector to hold std::unique_ptr<GameState> objects instead of raw GameState* pointers, and then delete will be called automatically for you when you remove objects from the vector.
Consider the following contrived example:
class AllocatedClass {
public:
AllocatedClass() : dummy(0) {}
private:
int dummy;
};
class AllocatingClass {
public:
AllocatingClass() : list() {}
~AllocatingClass() {
// CANNOT delete the elements in list here because there may
// be more than on instance of AllocatingClass sharing the same
// static list
}
AddNewObject() {
list.push_back(new AllocatedClass());
}
private:
static std::vector<AllocatedClass*> list;
};
In implemetation file
std::vector<AllocatedClass*> AllocatingClass::list;
Putting aside whether multiple instances of a class should share a list of dynamically allocated objects is a good idea, is there a way clean up these new'ed AllocatedClass objects at the end of the program? Does it matter if these never get deleted considering I don't want to delete them until application end?
If the lifetime of the object is the lifetime of the execution of the program then there is no need to free the memory with code. The memory will be free automatically.
Many Linux command line tools do not free their memory in code for performance reasons. (Faster to automatically free pages of memory, than to free each object one by one.)
Another strategy is to keep a separate list of unique AllocatedClass instances, then free them from that list later on (switching ownership of the objects). Like std::list<AllocatedClass*> to_be_freed.
is there a way clean up these new'ed AllocatedClass objects at the end
of the program?
One solution is to use std::shared_ptr and have the deallocation done automatically.
#include <memory>
#include <vector>
#include <iostream>
class AllocatedClass
{
public:
AllocatedClass(int n = 0) : dummy(n) {}
~AllocatedClass() { std::cout << "I am being destroyed" << '\n'; }
private:
int dummy;
};
class AllocatingClass
{
public:
AllocatingClass() {}
void AddNewObject(int num = 0)
{ shared_list.push_back(std::make_shared<AllocatedClass>(num)); }
private:
static std::vector<std::shared_ptr<AllocatedClass>> shared_list;
};
std::vector<std::shared_ptr<AllocatedClass>> AllocatingClass::shared_list;
AllocatingClass ac;
int main()
{
ac.AddNewObject();
ac.AddNewObject(1);
}
Live Example
Note that the destructors are called automatically for the objects that were placed in the vector.
(BTW, it isn't a good idea to name your member variable list).
Most of the time(very close to all the time) an object that creates dynamically allocated objects should have a programmer defined destructor to free the memory when the object reaches the end of its life. AllocatingClass should have a destructor because you allocate dynamic memory with new.
~AllocatingClass() {
for (int i = 0 ; i < list.size();i++) {
if(list[i] != NULL) {
delete list[i];
list[i] = NULL;
}
}
This should both provide a method for de-allocating memory and safety so that you do not delete an already deleted pointer.
I know that whenever I create a new object for a class, that object is stored in memory. I also know that in creating that object, it can only be accessed within the set of braces it is created in (Scope visibility). I need to find a way to delete that object outside of the braces it is created in. I have looked at smart pointers briefly, and it might be what I want to use? I'm assuming it is, I just don't know for sure. If a smart pointer can satisfy my needs, would someone please provide me with an example of how to use a smart pointer to access an object outside of where it has been created? Thanks :)
EDIT:
Example of what I'm trying to do:
class ModernWarfare2
{
//my class
ModernWarfare2();
};
DWORD XamHook(DWORD r3, DWORD r4, DWORD r5)
{
switch(XamGetCurrentTitleId())//a function that tells what game is being played
{
case Xbox360Dashboard://if i were to exit the game mw2
{
if(CODAllocated)//a boolean
{
//free the memory of the previous cod game
if(MW2Allocated)//another boolean
{
delete[] MW2;//gives me an error because i dont have access to MW2
}
}
break;
}
case COD_MW2:
{
if(!CODAllocated)
{
if(!MW2Allocated)
{
ModernWarfare2 *MW2 = new ModernWarfare2();
}
}
break;
}
}
return XamInputGetState(r3,r4,r5);
}
How do I fix my issue?
I also know that in creating that object, the object can only be accessed within the set of braces it is created in.
Not necessarily; that's only true when you construct objects with automatic storage duration, like this:
void foo()
{
T obj;
}
Such objects, yes, go out of scope.
Objects you allocate dynamically do not:
void foo()
{
T* obj = new T();
}
This is a memory leak because you never destroy *obj; however, you can access it from pretty much wherever you like:
T* foo()
{
return new T();
}
void bar()
{
T* obj = foo();
// yay!
}
or:
T* obj = nullptr;
void foo()
{
obj = new T();
}
void bar()
{
// do stuff with *obj
}
void baz()
{
foo();
bar();
}
This all gets dangerous and messy because you end up with spaghetti code in which the lifetime of the dynamically-allocated object is unclear, and in the examples above I still haven't approached the topic of eventually destroying the object. You have to be really careful not to destroy it whilst you're still using it.
This is where smart pointers come in, but if you want a tutorial on using smart pointers I'm going to have to refer you back to your C++11 book.
"I also know that in creating that object, the object can only be accessed within the set of braces it is created in." - This depends on how you create the object.
Example 1 (can't be accessed outside braces):
void func(void)
{
Object obj("foo", "bar");
}
Example 2 (can be accessed outside braces):
Object* func(void)
{
Object* obj = new Object("foo", "bar");
return obj;
}
Example 2 can be deleted using the keyword delete.
Take a look here for more information on pointers.
I haven't personally found a use for smart pointers but MSDN has good information on the topic here
By creating MW2 with
{
ModernWarfare2 *MW2 = new ModernWarfare2();
}
I was not able to reference MW2 elsewhere. By doing this, I can create it and delete it in two different spots:
class ModernWarfare2
{
//my class
ModernWarfare2();
};
ModernWarfare2 *MW2 = NULL;
DWORD XamHook(DWORD r3, DWORD r4, DWORD r5)
{
switch(XamGetCurrentTitleId())//a function that tells what game is being played
{
case Xbox360Dashboard://if i were to exit the game mw2
{
if(CODAllocated)//a boolean
{
//free the memory of the previous cod game
if(MW2Allocated)//another boolean
{
delete MW2;//gives me an error because i dont have access to MW2
}
}
break;
}
case COD_MW2:
{
if(!CODAllocated)
{
if(!MW2Allocated)
{
if(MW2 == NULL)
{
MW2 = new ModernWarfare2();
}
}
}
break;
}
}
return XamInputGetState(r3,r4,r5);
}
I think what you need is basic design pattern
Make the data and the functions members of a class
class SomeHandler
{
public:
void Acquire( /* some source */ );
void DoSomething( /* eventual parameters */ );
bool TrySomething(); // returns true if successful
private:
void internalFunction();
bool inGoodState;
SomeType dataINeed;
SomeOtherType otherData;
};
void SomeHandler::Acquire( /**/ )
{
// implement like this
}
now the functions can access the all the data
the use it like
int main()
{
SomeHandler h;
h.Acquire();
if( h.TrySomething() )
{
h.DoSomething();
}
}
Based on your code snippet, You have to save your pointer MW2 for
future so that you can delete the pointer.
I would suggest you to change
if(!MW2Allocated)
to
if(!MW2)
so that you don't have to create another variable for saving the reference to your allocated memory
Offcourse you have to move
ModernWarfare2 *MW2
to a larger scope (move it to the scope same as MW2Allocated) and initialize it to NULL.
Use "nullptr" instead of "NULL" if you are using C++11 supported compiler.
Also makesure you use
delete
instead of
delete[]
since this is not an array allocation
I don't think you can use smart pointers to skip saving your reference to the allocated memory,
since they are meant to make the memory deletion automatic or to make sure two deletion doesn't occur
for the same memory.
Refer to
http://www.codeproject.com/Articles/541067/Cplusplus-Smart-Pointers
for a good explanation about smart pointers
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
deleting memory allocated in static function in C++
Hi All,
I have C++ class as follows
interface myInterface;
class anotherClass : public myInterface {};
class myClass {
private:
myClass() {}
~myClass() {}
typedef std::map<string, myInterface* > stringToClass;
static stringToClass s_stringToClass;
public:
static myInterface& getStringToclass(string name);
};
in above class for getStringToClass defintion is as follows
myInterface& myClass::getStringToClass(string name) {
stringToClass::iterator iter;
iter = s_stringToClass.find(name);
if(iter == s_stringToClass.end()) {
typedef stringToClass::value_type stringToClassPair;
anotherClass* pothClass = new anotherClass();
s_stringToClass.insert(stringToClassPair(name, pothClass));
return pothClass;
}
else {
return iter->second;
}
}
now my question is we are allocating memory in static function and returning a pointer of class type, but here i want to retrun a reference as we don't want to give control of pointer to user. And also i don't want to delete immedetily unless user asked to or want to delete at end of program How can we delete memory? As there is only instance of class will be there, as there are only static functions.
Thanks for the help.
Note:
You should reformat on the old thread, instead of creating new question. Anyway, I paste my answer here.
I think in your case, the destructor won't help, because there is no any object of MyClass.
I propose three ways
1. Don't store pointer, store the object itself.
2. Put the delete function into atexit; In your case
class MyClass
{
.....//Your already existing code
static void Destroy()
{
//iterate s_StringToClass and delete them
}
static void getStringToClass( string name )
{
struct DestroySetter
{
DestroySetter()
{
atexit( MyClass::Destroy );
}
};
static DestroySetter setter; //Setup the destoyer
//Your existing code here
}
Use smart pointer to manage the resource, shared_ptr is recommended.
Though I put a lot in second way, I suggest the 3rd way.