Reputation: 711
So in C++ if I create an object useing new
I should always deallocate it using delete
For example
Segment::Segment(float length)
{
segmentLength = length;
angle = 0.0f;
x = Rand::randFloat(1.0f, 1.5f);
y = Rand::randFloat(1.0f, 1.5f);
vx = Rand::randFloat(0.0f, 1.0f);
vy = Rand::randFloat(0.0f, 1.0f);
prevX = Rand::randFloat(0.0f, 1.0f);
prevX = Rand::randFloat(0.0f, 1.0f);
};
And lets say I use it like this in another class such as,
this._segmentObject = Segment(2.0f);
this._segmentPointer = new Segment(2.0f);
In the destructor of that class, I know I should call delete
on the this._segmentPointer, however how do I make sure memory is deallocated for the other one?
Upvotes: 1
Views: 267
Reputation: 32490
The destructors for all class-type member objects are called at the time of the destruction of the primary class. So your this
object, which is allocated on the stack, will have it's destructor called when it goes out-of-scope. At that time, any class-type member objects of your this
object will have their own destructors called in addition to the destructor for your this
object which will call delete
on the member pointer.
For instance, take the following code sample:
#include <iostream>
using namespace std;
class A
{
public:
A() {}
~A() { cout << "Destructor for class A called" << endl; }
};
class B
{
private:
A a;
public:
B() {}
~B() { cout << "Destructor for class B called" << endl; }
};
int main()
{
B b;
return 0;
}
When run, the output becomes the following:
Destructor for class B called
Destructor for class A called
So you can see that when b
, which is allocated on the stack, goes out-of-scope at the end of main
, the destrutor for class B
is called, which in-turn, after executing the body of the destructor function, calls the destructors for any of its class-type member data objects, which in this case would mean the destructor for class A
. Therefore in your case, the pointer would have delete
called on it in the destructor for your this
class, and then the destructor for _segmentObject
would be called after the destructor for this
had completed execution of the body of its destructor. Then once all the destructors for the non-static data-member objects had been called, the destructor for this
then returns.
Upvotes: 1
Reputation: 8108
As others have said, you don't need to explicitly do anything to reclaim the memory used by this._segmentObject
. As soon as it goes out of scope, the memory will be reclaimed.
It's not clear why you would use Segment
in both ways. You should try to ensure you use the Resource Acquisition Is Initialization idiom, as it removes much of the need for checking new
/ delete
pairs. That is, just use the this._segmentObject
version, not the pointer.
Your application may not allow it, though.
Upvotes: 0
Reputation: 545508
however how do I make sure memory is deallocated for the other one?
It is automatically. This is why this type of storage is called automatic. Automatic storage is released at the end of the storage’s life cycle, and the objects’ destructors called.
The object life-cycle ends when the program control leaves the scope where the object has been allocated.
Upvotes: 5
Reputation: 90422
Things not allocated with new
, new[]
or the malloc
family should be destructed and "freed" when the object goes out of scope.
Often this simply means that that the code has reached the end of the block it was declared it or that the object that it was in was destructed (one way or another).
To see this in action, you can do something like this:
struct C {
C() { std::cout << "C()" << std::endl; }
~C() { std::cout << "~C()" << std::endl; }
};
struct B {
B() { std::cout << "B()" << std::endl; }
~B() { std::cout << "~B()" << std::endl; }
private:
C c_;
};
struct A {
A() { std::cout << "A()" << std::endl; }
~A() { std::cout << "~A()" << std::endl; }
};
int main() {
B *b = new B; // prints "B()", also constructs the member c_ printing "C()"
{ // starts a new block
A a; // prints "A()";
} // end of block and a's scope, prints "~A()"
delete b; // prints "~B()", also destructs member c_, printing "~C()"
}
Note: that if we did not do delete b
, the "~B()" and "~C()" would never print. Likewise, if c_
were a pointer allocated with new
, it would need to be delete
'd in order to print "~C()"
Upvotes: 4
Reputation: 5787
Not only that, You should only allocate with new and deallocate with delete in Constructors or Destructors, otherwise your program can leak if an exception is thrown.
Upvotes: 1
Reputation: 14786
The memory for this._segmentObject is part of the memory of the containing object, and will be released when the containing object is destroyed.
this._segmentObject is assigned from a temporary object that is created on the stack and deleted when it goes out of scope.
Upvotes: 3
Reputation: 3180
The _segmentObject is allocated automatically on the stack. The object destructor will be called automatically when the variable gets out of scope.
Upvotes: 0