I created the following class. Whenever the overloaded assignment operator is called, the program seems to deconstruct the object immediately afterwords. Whatever is actually happening, I consistently receive an error message immediately after the program executed the overloaded operator=().

This is the class:
Code:
class key
{
public:
	key(int);//key.length is set to the value passed to the constructor, which allocates the dynamic arrays
	~key();//The deconstructor deletes the dynamic arrays.
//More member functions
	key operator=(const key &rhs);/*This operator sets key.length = rhs.length, deletes and recreates the dynamic arrays, and copies the dynamic arrays in rhs into those in key.*/ //If rhs = key, the function simply executes "return this".
private:
	int *keyset;//keyset (key set) is a dynamic array
	bool *defined_keys;//defined_keys is a dynamic
	int length;//length is the length of the key set and one more than the highest numbered index of the dynamic array.
};

key::key(int set_length)
{//key.length is set to the value passed to the constructor.
	length = set_length;
	//Also, create the dynamic arrays.
	keyset = new int[set_length];
	defined_keys = new bool[set_length];
	//Rest of function omitted
}

key::~key()
{//The deconstructor deletes the dynamic arrays.
	delete [] keyset;
	delete [] defined_keys;
}

key key::operator=(const key &rhs)
{//This operator sets this.length = rhs.length, deletes and recreates the dynamic arrays, and copies the dynamic arrays in rhs into those in this.
	
	//If rhs == this, the function simply executes "return this" (at the end of the function).
	//This way, the dynamic arrays are not inadvertently destroyed in a self-assignment.
	if(this == &rhs)
	{
	}
	else
	{
		length = rhs.length;//Set this.length = rhs.length so the dynamic arrays can be correctly recreated
		
		//Delete the dynamic arrays so they can have new information put in them
		delete [] keyset;
		delete [] defined_keys;
		
		//Recreate the dynamic arrays with the new length
		keyset = new int[length];
		defined_keys = new bool[length];

		//Put the new information into the arrays
		for(int i=0;i<length;i++)
		{//Go through each index and copy the information in rhs to this
			defined_keys[i] = rhs.defined_keys[i];
			if(defined_keys[i] == DEFINED)
			{//Only copy information from rhs.keyset[i] to this.keyset[i] if rhs.keyset[i] is defined.
//(keyset's members are gradually defined as the program runs, but it is possible to call functions that can access any of its indexes at any time. defined_keys is a parallel array used to make sure that these functions only access defined indexes in keyset.)
				keyset[i] = rhs.keyset[i];
			}
		}
	}
	return *this;
}
This is a structure that uses the key class:
Code:
struct full_set
{
	key n,e,d;
	full_set(int length)//The constructor sets the length of all the keys by calling their constructors. Because of what the program is supposed to do, all the keys have the same lengths.
	: n(length), e(length), d(length)
	{}
	full_set operator=(const full_set &rhs)
	{//The assignement operator calls the assignment operators for the key objects, which are also overloaded.
		n.operator=(rhs.n);
		e.operator=(rhs.e);
		d.operator=(rhs.d);
		return *this;
	}
};
This is the declaration of generate_keys, a function I used while testing the overloaded operator=:
Code:
full_set generate_keys(int length);
This is one function I've tried using to test the overloaded operator=:
Code:
int main()
{
	full_set test(1);
	test = generate_keys(1);//The program errors out here.
	cout << test.n.get_value(0) << endl
		<< test.e.get_value(0) << endl
		<< test.d.get_value(0);
	cin.get();

	return 0;
}
While test.operator=() runs, there are no errors. After each call of key.operator=() runs, ~key() (the deconstructor) is called. I don't understand why. I'm pretty sure that when n.operator=(rhs.n) is called, n is deconstructed afterwards, and the same thing happens to e and d. Immediately after the program completes test.operator=(), I get the error below.

I also tested the overloaded operator= with this function:
Code:
int main()
{
	full_set test(1);

	test.n = generate_keys(1).n;
	cout << test.n.get_value(0) << endl;
		//<< test.e.get_value(0) << endl
		//<< test.d.get_value(0);
	cin.get();

	return 0;
}
In this case, immediately after test.n,operator=() runs, the deconstructor runs and probably deconstructs n. After the deconstructor runs and the program returns to the main function, I get the error.

This is the error:
Debug Assertion Failed!

Program: [location of the executable]
File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp [I don't have a drive labeled f: on my computer. ?]
Line: 52

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)
From what I've read on other forums, I understand that the _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) error occurs when the program executes the delete command on a pointer that has already been deallocated. I don't understand why the deconstructor has been called at all or why I get this error after the deconstructor is successfully executed.

I want the program to complete key.operator= by having all the members in the left-hand object have the same values as those in the right-hand object except for the indexes in key.keyset[] that have not been explicitly defined in the right-hand object. For instance, this code:
Code:
key a(2),b(3);
//Program sets b.keyset[0] = 0 and b.keyset[1] = 1 and doesn't set b.keyset[2].
//In paralell, b.defined_keys[0] and b.defined_keys[1] are set to true to show that the corresponding indexes in b.keyset are defined. b.defined_keys[2] = false.
a = b;
Should end with a.length == 3, a.keyset == {0,1,?}, and a.defined_keys == {true,true,false}.

What is causing the deconstructor to run? What should I do to fix the error and have my program run as I expect it to?