Hi All,

While executing below code without using assigment operator it works fine , eventhough i have been used pointer
values, so any way it must crash as The memory that s2 used to point to was never deleted;
it is lost forever as both a and b now point to same place When one of them goes out of scope, its destructor will delete the same memory. Both are allocated object so memory crash must be happend and it is expected here.

~Mohan

#include<iostream.h>
#include<conio.h>

using namespace std;

class Derived1 
{ 
int *m_p;
public:
Derived1 ();
Derived1& operator =( const Derived1 &obj);
void show()const  {cout<<"integer="<<*m_p<<endl;}
void setVal(int);
~Derived1(){ 

delete m_p;
//m_p=NULL;}
}
};

void Derived1::setVal(int val)
{
*m_p = val;
}


 Derived1::Derived1()
 {    
     m_p=new int(0);   
 }

 Derived1& Derived1::operator=(const Derived1 &obj)
       {
       int *ptr= new int (*obj.m_p);
        delete  m_p;
        m_p=ptr;
        return *this;
       }

int main()
{

  Derived1 s1 ;
  s1.setVal(20);
  s1.show();
  Derived1 s2;
  s2.setVal(100);
  s2.show();
  s2=s1;
  s1.show();
  s2.show();

  getch();


}

For a better view over your program, consider this extension to your program:
add a new private member called name (string) which will hold the object name.
put a cout in your desctructor with the name of your object:

#include<iostream>
#include <string>
#include<conio.h>

using namespace std;

class Derived1
{
int *m_p;
string name;
public:
Derived1 (string n);
Derived1& operator =( const Derived1 &obj);
void show()const  {cout<<"integer="<<*m_p<<endl;}
void setVal(int);
~Derived1(){
    cout<<"called by "<<name<<endl;
    delete m_p;
//m_p=NULL;}
    }
};

void Derived1::setVal(int val){
    *m_p = val;
}


 Derived1::Derived1(string name)
 {
     this->name = name;
     m_p=new int(0);
 }

 Derived1& Derived1::operator=(const Derived1 &obj)
       {
       int *ptr= new int (*obj.m_p);
        delete  m_p;
        m_p=ptr;
        return *this;
       }

int main(){
  Derived1 s1("s1") ;
  s1.setVal(20);
  s1.show();
  Derived1 s2("s2");
  s2.setVal(100);
  s2.show();

  s2=s1;
  s1.show();
  s2.show();

//  getch();


}

What is the output of this?

And than, another test but commenting out the assignment operator, and making s2 a pointer:

// Derived1& Derived1::operator=(const Derived1 &obj)
//       {
//       int *ptr= new int (*obj.m_p);
//        delete  m_p;
//        m_p=ptr;
//        return *this;
//       }

int main(){
  Derived1 s1("s1") ;
  s1.setVal(20);
  s1.show();
  Derived1* s2 = new Derived1("s2");
  s2->setVal(100);
  s2->show();

  s2=&s1;
  s1.show();
  s2->show();

}

Edited 3 Years Ago by Lucaci Andrew

Hi,
Without commenting assignment operator it doesn't copy the string object of s1 into s2 object but copy the number field properly. but in other case while commenting the assignment operator it does assignment successfully.

but my question was in absence of assignment operator , why there is no memory leaked has been seen.

Regards,
Mohan

I also tried with code snippet given by you and found one more issue so it can't be used as a replacement of assignment operator

   1. int main()
   2. {
   3. Derived1 s1("s1");
   4.
   5. s1.setVal(20);
   6. s1.show();
   7.
   8. Derived1* s2 = new Derived1("s2");
   9. s2->setVal(100);
  10. s2->show();
  11.
  12. s2=&s1; // this is aiming s2 at the memory for s1 (and leaking the old memory for s2 that you newed)
  13.
  14. s1.show(); // Shows s1
  15. s2->show(); // Also shows s1!
  16.
  17. // Now try to change s2
  18. s2->SetValue( 5 );
  19.
  20. s1.show(); // Now s1 has the same value that you just put into s2!
  21.
  22. getch();
  23. }

s2=&s1; // this is aiming s2 at the memory for s1 (and leaking the old memory for s2 that you newed)

It's not leaking the old memory from s2. When the object goes out of scope, i.e. cannot be referenced or be reused in your program (or to be "revived"), the destructor is called automatically, thus freeing the memory of the s2 pointer.

  1. // Now try to change s2
  2. s2->SetValue( 5 );
  3. s1.show(); // Now s1 has the same value that you just put into s2!

That is correct. By assigning to the pointer s2 the memory address of s1, they both will "point" to the same memory part, thus every change done to each of them will affect the other.

A good way to copy an object is either overload the equality operator, or create a copy constructor.

Here's a version of a copy constructor for Derived1:

#include <iostream>
#include <string>
using namespace std;

class Derived1{
    int *m_p;
    string name;
public:
    Derived1 (string n);
    Derived1 (const Derived1&); //copy constructor
    Derived1& operator =( const Derived1 &obj);
    void show()const  {cout<<"Name: "<<name<<" integer= "<<*m_p<<endl;}
    void setVal(int);
    void setName(string name){this->name=name;}
    ~Derived1(){
        cout<<"called by "<<name<<endl;
        delete m_p;
    }
};

Derived1::Derived1(const Derived1 &obj){ //here you copy the object obj
    this->m_p = new int(*obj.m_p);
    this->name = obj.name;
}

void Derived1::setVal(int val){
    *m_p = val;
}

Derived1::Derived1(string name){
    this->name = name;
    m_p=new int(0);
}

Derived1& Derived1::operator=(const Derived1 &obj){
    int *ptr= new int (*obj.m_p);
    delete  m_p;
    m_p=ptr;
    return *this;
}

int main(){
    Derived1 s1("s1") ;
    s1.setVal(20);
    s1.show();
    Derived1 s2(s1); //Here you create a copy of s1 in s2.
    s2.show();
    cout<<"Setting s2's name to 's2'\n";
    s2.setName("s2");
    s2.setVal(100);
    cout<<"Modifying s2's content to 100: \n";
    s2.show();
    cout<<"s1: \n";
    s1.show();
}

Edited 3 Years Ago by Lucaci Andrew

It's not leaking the old memory from s2. When the object goes out of scope, i.e. cannot be referenced or be reused in your program (or to be "revived"), the destructor is called automatically, thus freeing the memory of the s2 pointer.

I'm afraid you have mis-understood how memory managerment works in C++. You have to keep a record somewhere of the address in memory that you want to call delete on for every item that you new. If you use new to allocate memory on the heap, you have to free it yourself, there is no mechanism in C++ to know when nothing can reference memory that you've allocated. Once you lose the address (like you do if you re-assign the pointer that refers to the memory) then it's gone and you have a memory leak.

You can get around this issue by using smart pointers.

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