Hi
I created a class,simplified class is like below:

#include<iostream.h>


class cCat
{
public:
//Constructors and Destructors
cCat();
~cCat();


//Accessor Function
int & cCat::GetAge() const{ return *itsAge;}


//Convertion operator
cCat(int);  // cCat object =int x


private:
int *itsAge;
};


cCat::cCat()
{
itsAge = new int;
*itsAge= 20;
}
cCat::~cCat()
{
}


//Convertion Operator
cCat::cCat(int Age)
{
itsAge= new int;
*itsAge=Age;
}


main()
{
cCat MyCat(23);
cout<<"My Cat age:"<<MyCat.GetAge();
MyCat=42; //this makes a memory leak


return 0;
}

As the code shows MyCat(23) and MyCat=42 statements have the same definition in the class and this makes a memory leak.(cause without deleting previous allocated memory I allocate a new memory in cCat(int Age)

so,how can I avoid this memory leak?

Edited 3 Years Ago by Nick Evan: Fixed formatting

Heck, your destructor causes a memory leak too. You should delete age there.

There may be good reasons for a pointer to int here, but in this simple example an int would work fine, wouldn't it? But, assuming there's more to this....

= is an assignment operator, so it doesn't go through the constructor code. Since you don't define an assignment operator, the compiler figured out that it could turn the int into a cCat by calling the constructor, and then it could just copy en-masse the bytes over. Another leak!

Add an assignment operator:

cCat& operator = ( int age ) { *itsAge = age; return this; }

(I didn't try this out in the compiler, but you can get the syntax right when you do)

Remember that in an assignment operator, the object has already been constructed. As opposed to a copy constructor, in which the object has not already been constructed. The compiler will supply a default if it can, and the default will NOT be sensitive to allocated ram.

Hi
Thanks for your help

I used a reference to int cause my int doesn't go out if scope after returning of my function so I tried to do this to avoid making a temporary int , and program be faster ,If I am wrong tell me ,I would be happy to know.

and about destructors, I saw some codes of a book that where written like this (I in destructors no delete wasn't suppied).
I think that it wouldn't make a memory leak cause my objects stay alife to end of the program and at end of it memory will become freed automatically

except when I create a pointer to my class,and allocate memory for it
are these corrrect?

thanks for your helps again

About the ptr to int/ref to int thing: the memory allocated for the class instance of cCat holds, in your case, a pointer. But holding an int is really the same in terms of what happens to the CLASS instance; if you return a cCat from a function the out-of-scope stuff still applies whether a member of the class is a pointer or not.

So, in this case, I think an int is perfectly adequate. If you had issues with returning the cCat from a routine, you might want to do a new on the whole cCat object, and return a pointer to the cCat. Like this:

cCat* GetACat(int age)
{
    return new cCat(age);
}

and then the caller has to 'delete' the return value when she's done. Generally, it would be easier to use something like this, unless there is a benefit for the allocated memory:

void GetCat( cCat* myCat, int age )
{
    myCat->SetAge(age);
}
- or -
void GetCatByRef( cCat& myCat, int age )
{
    myCat.SetAge(age);
}

To use, you would do something like this:

cCat myCat; // local space, not allocated
GetCat( &myCat, 23 ); // in the first version
GetCatByRef( myCat, 23 ); // in the second version

As to the destructor, you are correct that, in this specific case, the memory is freed when you exit your program. Though, when you originally mentioned a leak, the same thing would apply. You could leak a TON of memory and that would be ok since you exit the program.

Still, leaking ram is like running a stop sign. Someday you will get caught. Get in the habit of watching out for leaks and that good habit will save your keester someday.

Generally, if you allocate space in your class with new, you will want to:
a) set the pointer to NULL in your constructor, and
b) delete the pointer in your destructor, and
c) watch out for the assignment operator (do not let the compiler generate one for you, it will be wrong), and
d) make a copy constructor that allocates ram for the copy (again the compiler will be happy to generate the WRONG code for you)

If you put somthing in your destructor, you should also get in the good habit of declaring the destructor 'virtual' unless you have a clear reason for not doing that. Good reasons might include a tiny object that will NEVER have a subclass and there will be MILLIONS of them, so the saved pointer is truly a benefit.

a virtual destructor in this case also has no benefit yet, but if you do it as rote you won't make a mistake of that kind in a larger program where someone makes a subclass called 'cKitten' and you have a leak again.

Just sage advice.

Thanks chainsaw for your great advices
I think that it would be better to use int instead of int & as your told
and also thanks for your nice adivces in using Pointer and declaring Constuctors and destructors.

Thanks again

Sincerely
the_one2003a

This article has been dead for over six months. Start a new discussion instead.