Reference counting & Copy on write


The problem when using default copy constructor is if the source contains any pointer types then the destination also points to the same address . So when the source object goes out of scope , deferencing the pointer type from the destination results in Segfault . So that’s why we override the default copy constructor in most cases. Now in high performance application creating a new object in the copy constructor seriously hinders performance . So instead of creating object , the pointer in destination object is just made to point the source object pointer until & unless you want to perform a write action on the object . I’m posting the code which was causing some Segfaults in the destructor and was a pain the ass . Finally it’s corrected . I guess you will enjoy the beauty of c++ and appreciate it’s elegance and power .

#include<iostream>
#include<cstring>

using namespace std;

class Dog
{
	string name;
   int count;

	public:

	Dog(string _name):name(_name),count(1)
	{
	
		cout<<name<<":: The count value is "<<count<<endl;
	}

	Dog ( Dog & ob):name(ob.name),count(1)
	{ 
	
    cout<<name<<":: The count value is "<<count<<endl;	
	}

	void Attach()
	{

		count++;
		cout<<name<<":: The count value is "<<count<<endl;
	}

	void Deattach()
	{
		count -- ;

		cout<<name<<":: The count value is "<<count<<endl;

		if( count ==0)
		{
			cout<<name<<":: Deleted object"<<endl;
			delete this;
		
		}
	}

	Dog*  Alias()
	{
		if( count ==1 )
			return this;
		else
			return new Dog(*this);

	}

	void Setname(string _name)
	{

		name=_name;
	}

};

class Doghouse
{
	Dog *dog;
	string house_name;

	public:

	Doghouse(string _house_name)
	{
		house_name=house_name;
	}

	Doghouse(Dog *_dog, string _house_name):dog(_dog),house_name(_house_name){
	cout<<"The house name is "<<house_name<<endl;
	}
	Doghouse(Doghouse & dh)
	{

		house_name=dh.house_name;
		dog=dh.dog;
		dog->Attach();

	}
	
	Doghouse& operator = (const Doghouse& dh)
	{

		dog->Deattach();
		dog=dh.dog;
		house_name=dh.house_name;
		dog->Attach();
	
	}

	void Alias()
	{
		dog=dog->Alias();
	}

	void rename_dog(string _name)
	{

		Alias();
		dog->Setname(_name);



	}

	~Doghouse()
	{

		dog->Deattach();

	}

	};


int main()
{

	Dog *d1=new Dog("Peggy");
	Dog *d2=new Dog("Hussky");

	Doghouse dh(d1,"kennel");
	Doghouse dh1=dh;
   Doghouse dh2(d2,"kennel2");
	dh2=dh1;

	dh2.rename_dog("husskie");

}
  
Advertisements

5 responses to this post.

  1. Hey, Nice post.I am not very clear on this idea, I have one doubt that is, when you copy only on a write still segfault might happen right?
    For instance, object B has a pointer that is pointing to a data of object A. Before you write a value to B (only when you will create a copy) if you delete A, then the subsequent write might cause a segfault. Am I right?

    Reply

  2. Posted by abhi74k on November 25, 2010 at 9:32 am

    Thanks … Suppose when both A & B point to an object and if i delete A then i just decrement the reference counter without deallocating space for it . Just like count variable in inode block . Only when one pointer is pointing to object i actually dellocate space for the object .

    Reply

  3. Posted by Biswabandan on November 25, 2010 at 3:26 pm

    nice explanation

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: