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:
This is a structure that uses the key 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 the declaration of generate_keys, a function I used while testing the overloaded operator=: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 one function I've tried using to test the overloaded operator=:Code:full_set generate_keys(int length);
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.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; }
I also tested the overloaded operator= with this function:
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.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; }
This is the error:
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.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)
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:
Should end with a.length == 3, a.keyset == {0,1,?}, and a.defined_keys == {true,true,false}.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;
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?


Reply With Quote

Bookmarks