This question relates to C++ game engine, called AppGameKit (AGK).
I've created a separate class for Text so that I don't have to call AGK functions when creating Text. Here's the simple class:
Text.h
class Text
{
private: int _ID;
void Destory();
public:
void AddText();
Text(int ID);
~Text();
};
Text::Destroy()
{
agk::DeleteText(_ID);
}
Text::~Text()
{
Text::Destroy();
}
Now my question is when I'm calling this class in any other class, say MainMenu, do I have to delete the button in the class MainMenu that I'm creating using this class or will the destructor of Text will automatically get called and delete the button.
MainMenu.cpp
MainMenu::Initilization()
{
Text * mainText = new Text(1);
}
MainMenu::Destory()
{
agk::DeleteText(1); // DO I HAVE TO DO THIS?
}
MainMenu::~MainMenu()
{
MainMenu::Destory();
}
AGK function delete is called to delete text so that the memory is deallocated. Similar to C++ delete keyword.
Personally, I think deleting the button in MainMenu class should be unnecessary but I'm confused as to whether the destructor of Text class is even called. Please let me know if you think I'm wrong.
Every new has to be balanced with a delete else you will leak memory. (You can use classes like std::unique_ptr which will manage the deletion for you but they still call delete under the hood).
Currently, mainText goes out of scope at the end of the Initilization function, so you lose the pointer that you need for a successful delete.
Do I have to manually delete object even after destructor?
No.
You called Text * mainText = new Text(1); in Initialization, so call delete mainText in Destroy
When you call delete mainText
If mainText is not null its destructor would be called
If mainText is not null its memory would be freed
No need to mention, the destructor already calls agk::DeleteText
The basic rule of thumb in C++ is for every new() there must be a delete(). This ensures that there would be no memory leakage.
In most modern OS, there is no memory leakage ever. Once your program exits, the OS claims back the memory and puts it back in heap.
But what happens when your program is running for a long time. This means you will keep leaking memory until your program exits.
So it's best to delete the allocated memory and adhere to the rule of thumb.
Hope it helps!!
Related
I have the following code and I get stack overflow error can anyone please explain me What's wrong here. from my understanding this pointer points to current object so why I cant delete it in a destructor;
class Object
{
private:
static int objCount;
public:
int getCount()
{
int i =10;
return i++;
}
Object()
{
cout<< "Obj Created = "<<++objCount<<endl;
cout <<endl<<this->getCount()<<endl;
}
~Object()
{
cout<<"Destructor Called\n"<<"Deleted Obj="<<objCount--<<endl;
delete this;
}
};
int Object::objCount = 0;
int _tmain(int argc, _TCHAR* argv[])
{
{
Object obj1;
}
{
Object *obj2 = new Object();
}
getchar();
return 0;
}
You're doing delete this; in your class's destructor.
Well, delete calls the class's destructor.
You're doing delete this; in your class's destructor.
...
<!<!<!Stack Overflow!>!>!>
(Sorry guys I feel obliged to include this... this might probably spoil it sorrrryyyy!
Moral of the boring story, don't do delete this; on your destructor (or don't do it at all!)
Do [1]
Object *obj = new Object();
delete obj;
or much better, just
Object obj;
[1]#kfsone's answer more accurately points out that the stack overflow was actually triggered by obj1's destructor.
'delete this' never makes sense. Either you're causing an infinite recursion, as here, or you're deleting an object while it is still in use by somebody else. Just remove it. The object is already being deleted: that's why you're in the destructor.
The crash you are having is because of the following statement:
{
Object obj1;
}
This allocates an instance of "Object" on the stack. The scope you created it in ends, so the object goes out of scope, so the destructor (Object::~Object) is invoked.
{
Object obj1;
// automatic
obj1.~Object();
}
This means that the next instruction the application will encounter is
delete this;
There are two problems right here:
delete calls the object's destructor, so your destructor indirectly calls your destructor which indirectly calls your destructor which ...
After the destructor call, delete attempts to return the object's memory to the place where new obtains it from.
By contrast
{
Object *obj2 = new Object();
}
This creates a stack variable, obj2 which is a pointer. It allocates memory on the heap to store an instance of Object, calls it's default constructor, and stores the address of the new instance in obj2.
Then obj2 goes out of scope and nothing happens. The Object is not released, nor is it's destructor called: C++ does not have automatic garbage collection and does not do anything special when a pointer goes out of scope - it certainly doesn't release the memory.
This is a memory leak.
Rule of thumb: delete calls should be matched with new calls, delete [] with new []. In particular, try to keep new and delete in matching zones of authority. The following is an example of mismatched ownership/authority/responsibility:
auto* x = xFactory();
delete x;
Likewise
auto* y = new Object;
y->makeItStop();
Instead you should prefer
// If you require a function call to allocate it, match a function to release it.
auto* x = xFactory();
xTerminate(x); // ok, I just chose the name for humor value, Dr Who fan.
// If you have to allocate it yourself, you should be responsible for releasing it.
auto* y = new Object;
delete y;
C++ has container classes that will manage object lifetime of pointers for you, see std::shared_ptr, std::unique_ptr.
There are two issues here:
You are using delete, which is generally a code smell
You are using delete this, which has several issues
Guideline: You should not use new and delete.
Rationale:
using delete explicitly instead of relying on smart pointers (and automatic cleanup in general) is brittle, not only is the ownership of a raw pointer unclear (are you sure you should be deleting it ?) but it is also unclear whether you actually call delete on every single codepath that needs it, especially in the presence of exceptions => do your sanity (and that of your fellows) a favor, don't use it.
using new is also error-prone. First of all, are you sure you need to allocate memory on the heap ? C++ allows to allocate on the stack and the C++ Standard Library has containers (vector, map, ...) so the actual instances where dynamic allocation is necessary are few and far between. Furthermore, as mentioned, if you ever reach for dynamic allocation you should be using smart pointers; in order to avoid subtle order of execution issues it is recommend you use factory functions: make_shared and make_unique (1) to build said smart pointers.
(1) make_unique is not available in C++11, only in C++14, it can trivially be implemented though (using new, of course :p)
Guideline: You shall not use delete this.
Rationale:
Using delete this means, quite literally, sawing off the branch you are sitting on.
The argument to delete should always be a dynamically allocated pointer; therefore should you inadvertently allocate an instance of the object on the stack you are most likely to crash the program.
The execution of the method continues past this statement, for example destructors of local objects will be executed. This is like walking on the ghost of the object, don't look down!
Should a method containing this statement throw an exception or report an error, it is difficult to appraise whether the object was successfully destroyed or not; and trying again is not an option.
I have seen several example of usage, but none that could not have used a traditional alternative instead.
Im new to this and just wanted to ask a quick question about deleting objects.
I have an object called MyClass1 and from it I have a number of other classes, MyClassA, MyClassB etc.
Now should I do this in MyClass1:
MyClass1::~MyClass1()
{
delete MyClassA;
delete MyClassB;
}
Or will everything created in MyClass1 automatically be deleted when I delete MyClass1?
Also, if I have more objects created in MyClassA and MyClassB, will these also have to be deleted manually in their respective class?
Thanks
If you're asking this, you're just learning C++, so the best advice is - neither. You should know about this stuff (dynamic allocation & memory management - see Guillaume's answer for this), but what you really should do is use RAII (google this). The proper C++ way of doing it would be:
struct MyClass1
{
MyClassA mA;
std::shared_ptr<MyClassB> mB;
MyClass1() : mB(new MyClassB)
{
}
};
See? No more destructor, which means you also don't need a copy constructor or copy assignment operator (which is where Guillaume's answer is flawed - it's missing the last two).
call delete operator only if you have created your objects with new operator
struct MyClass1
{
MyClassA mA;
MyClassB * mB;
MyClass1()
{
mB = new MyClassB;
}
~MyClass1()
{
delete mB;
}
};
You can't delete objects that aren't pointers because that's not the purpose of delete. It's meant to free dynamic memory associated with an object. That is, whatever is created with new must be deleted. You can have pointers to a class, and they can be deleted. But since nothing was allocated with new, there's no need to use delete. The class will in fact be destructed from memory at the end of the scope in which it is created. Those objects are allocated on the stack while dynamic memory is on the heap. Objects on the stack have automatic storage duration (deleted at the end of its scope, unless its declared static in which case it has "static" storage duration); moreover, objects on the heap have dynamic storage duration. Dynamic memory in C++ is controlled by you, that's why we are given new and delete (because C++ expects us to handle the memory ourselves). And otherwise deleting an object not constructed with new is undefined behavior and may lead to a crash.
If Qt, use QPointer! It is a smart pointer: nothing needed in destructor.
#include <QPointer>
class MyClass1
{
QPointer<MyClassA> pA;
QPointer<MyClassB> pB;
};
delete is applied to objects, not to classes. As a rule, calling delete (or arranging to have it called automatically, via a shared pointer, or with the RAII idiom in general) is necessary only if you called new to create the object. The exception is the return value of some (library?) call being an object that the (library's?) documentation states explicitly that the caller has to dispose of with delete (in which case, think of the call as a wrapper around a new that you have become responsible for.) Of course, APIs like that should be avoided if at all possible.
I'm wonder to know is it possible to delete an object through destructor method?
Constructor and destructor of my class:
class cal
{
public:
cal()
{
days = 0;
day = 1;
month = 1;
year = 1300;
leap = true;
};
~cal()
{
delete this;
}
}*calendar = new cal;
How can I delete this pointer through class?
P.S
I forgot to write the following code
cal *calandar = new cal[];
I want to use it in heap not stack
I want to use this class (objects) frequently (many of that object) imagine how many time should I write delete and it make hard understanding, troubleshooting and tracing codes I want them to been destroyed automatically (in heap)
I used following code in my class when I exec "delete[] calendar" it reduce my rams occupied (amount of ram that is used) does it work properly (destroy all objects) by exiting program? Because I use GNU/Linus and it destructs all objects with or without that lines I'm concern about leaking in windows
void DisposeObject() { delete this; }
No. By the time the destructor is called, the object is already being destroyed, so delete this is not valid.
The behaviour is undefined, but most likely it will call the destructor recursively, leading to a stack overflow.
You can write the code like this:
class cal
{
public:
cal()
{
};
~cal()
{
}
void DisposeObject()
{
delete this;
}
}
And it will call your destructor.
You should not call delete this from your destructor since it will call the destructor recursively, possibly leading to a stack overflow. Anyway, the code you wrote suffers from undefined behavior.
Refer to this question for in-depth discussion: Is delete this allowed?
I`m wonder to know is it possible to delete an object through destructor method
Even supposing this was valid - The problem is that nothing would ever call the destructor, so this would never have an effect. The destructor is called when the calling code deletes the object, which in turn can delete any internal objects as needed.
In your case, it doesn't look like you need to do anything in your destructor, however, as you don't have any resources being allocated that need to be explicitly deleted (at least in what you're showing).
Following class will be initiated with a member variable newTodayTaskString (string).
When destructing the object I like to delete the string but when compiling the project I get an error message pointing to the destructor delete line saying:
delete: std::string cannot be converted to void
Class:
class TodayTask {
private:
string newTodayTaskString;
public:
TodayTask (string t) : newTodayTaskString (t){}
// Destr.
~TodayTask () {
delete newTodayTaskString;
}
string getTodayTaskString () const {
return newTodayTaskString;
}
};
delete must be given a pointer, and can only be used to destroy objects created with new.
In this case, the object is a class member, and so will be destroyed automatically. You don't need to do anything with it in the destructor.
In c++, memory can be allocated either automaticaly or manualy.
If you define a simple variable, the memory for it is allocated automaticaly, in the Stack. The memory is then automatically freed. For example:
void foo()
{
std::string s;//memory is allocated here
}//the variable only lives inside the function, so at this point the memory is freed
The second way is to allocate the memory manualy, with the operator new, like this:
void foo()
{
int * i = new int();//we allocate the memory for our variable here.
}
Here, the memory is alocated in the heap, and it will not be freed automaticaly in the end of the funciton, or anywhere else until your programm ends.
In this case, you need to call operator delete, but you must call it only once for each variable:
void foo()
{
int * i = new int();
<...some code...>
delete i;//we free the memory at this point.
}
Note that if you will try to delete the same variable twice, you might get a segmentation fault.
In your case you are trying to manualy delete a variable for which you have not manually allocated the memory, which leads to the error. In your case you don't need to bother with the destructor, everything will be done automaticaly.
delete is only needed when the object is created using new. In this case, your object is automatically created before the constructor since it is a member variable. Thus, it is automatically destroyed after the destructor is called.
You should use delete only when you created it using new
You don't 'delete' newTodayTaskString, since it hasn't been allocated with 'new'. It's a member variable -- it will be automatically constructed and destructed, there's nothing you have to do.
You don't need to delete newTodayTaskString as it is not you who allocates its memory
You really don't have to delete the string. It's not dynamically allocated.
Just remember this:
use delete when you new something.
use delete[] when you new an array of something.
I was reading this question Does calling a destructor explicitly destroy an object completely? where this situation comes up in code.
Object* aWidget = new Widget(); //allocate and construct
aWidget->~Object(); //destroy and DON'T deallocate
From the answers, I undrestand that the memory region is in fact not deallocated in this situation. My question is (more out of curiosity than anything):
How can I delete the memory pointed to by aWidget after the two lines of code above have executed? I would assume calling delete aWidget; would fail because it would try to run the destructor on an already-destructed object. Could you call free(aWidget) or something like that instead to just target the memory?
free would, factually speaking, be my best guess. However I don't think you can do anything without invoking UB. How did you arrive at a requirement to invoke the destructor like that?
Calling free on an object allocated with new is undefined behavior.
I suggest you keep it simple, and call delete.
However, if you want to do this, you can, in some cases, call delete even if you previously called the destructor explicitly. If you call it explicitly, you can view it as a function. The memory isn't freed, so I'm guessing setting member pointers to NULL after you destroy them would be enough to prevent you from running into any trouble. (because calling delete on a NULL pointer is a no-op).
For example, the following should be ok:
class A
{
public:
int * x;
A()
{
x = new int[10];
}
~A()
{
delete[] x;
x = NULL;
}
};
int main()
{
A* a = new A;
a->~A();
delete a;
return 0;
}