Quote:Original post by NightCabbage
Ok, I guess I just need to get my head around cleaning stuff up :)
So if I make anything, a string, an array, a texture, a struct, etc. I have to clean it up, right?
(by setting it to NULL? or calling the destructor? or just when it loses scope?)
To simplify things, I'm gonna pretend that all memory is either allocated on the stack (local) or the heap (dynamic). If you don't know about the stack and the heap, get yourself an "Intro to operating systems" book.
In Java, when you create a new object, the object itself is created on the heap, and your local variable (which references that new object) exists on the stack. Stack variables are local, so they can go out of scope. When your local reference goes out of scope, there are no more references to the object, so Java will automagically delete the object from the heap for you.
In C++, things are a bit trickier - you can choose to put objects on either the stack or the heap! Also, the language doesn't keep track of heap objects for you, which means if you don't have a pointer (C++ pointer = Java reference) to the object anymore, it will be leaked.
If you create an object on the stack, it will clean itself up when it goes out of scope. If you create an object on the heap, it will remain there until you delete it.
class Object{ Object() { /*constructor code*/ } ~Object() { /*destructor code*/ } void DoSomething() {}};void CreateOnStack(){ if( true ) { Object bob;//this creates a new object on the stack and calls the constructor bob.DoSomething();//When using an object directly, use the "." operator }//the object goes out of scope here and automatically calls the destructor}void CreateOnHeap(){ //N.B. This is a 'pointer' to an object (because of the *) Object* bob;//this creates a local variable which *can* contain a memory address of an object bob = new Object;//this creates a new object on the heap, calls the constructor and stores it's address in 'bob' bob->DoSomething();//When using an object through a pointer, use the "->" operator delete bob;//this calls the destructor, and releases the memory from the heap bob = NULL;//bob still contains the memory address that the object was using, but the object is now deleted! So it's a good idea to throw away that old address by setting it to NULL!}void CreateLeak(){ if( true ) { Object* bob = new Object;//Create object on heap, call constructor } //Oh no! Our pointer has gone out of scope, but the object still exists on the heap. We no longer know what it's address is, so we can't possibly delete it!}void CreateDanglingPointer(){ Object* bill = NULL;//If a pointer hasn't been set to an object yet, it's a good idea to set it to NULL/zero, so that you know it's not pointer to anything! if( true ) { Object* bob = new Object;//Create object on heap, call constructor bill = bob;//copy the address into bill as well delete bob;//Call destructor, free memory bob = NULL;//Good practice } bill->DoSomething();//This will crash! As bill contains the memory address of an object which has been deleted!}