Tuesday, December 30, 2008

Debug Assertion Failed! _BLOCK_TYPE_IS_VALID

You are getting the error because the program is trying to delete the same dynamically allocated array twice. You're not supposed to delete something that has already been deleted.In both cases, the code that is doing the deleting is the destructor of the Customer class.The destructor is trying to delete the same arrays twice because you have two separate Customer objects with the same pointer values. Each Customer object thinks it owns the arrays, so each object's destructor tries to delete the arrays when the object is destroyed. The first attempt to delete an array works; the second generates the error you have seen.One of these objects is the myC object visible in the main function. When control leaves that function, the myC object automatically gets destroyed.The other Customer object is an element of the data array in the Queue object myQ. When control leaves the main function, the myQ object as well as the myC object gets destroyed. The Queue destructor uses the delete [] operator on the data array, and that calls the destructor for each array element.One of those elements got its pointers set to the values in the myC object by the assignment statement in the enqueue function: data[rear] = elem;After this statement, both the Customer objects data[rear] and myC had the same values in their pointer members, so both objects thought they were responsible for deallocating the dynamically allocated memory addressed by the pointers. This statement also leaks the memory allocated when the data[rear] object was created: those pointer values are wiped out, so there is no way to free the memory.Usually when you have a class that owns other dynamically allocated objects or arrays, you need to give the class an assignment operator, a copy constructor, and a destructor, to prevent just such problems as this. In fact, there is in C++ lore a "Law of the Big Three," which says that if you need any one of these, you probably need all three. When you assigned elem to data[rear], you probably wanted the strings to be copied, but since the strings are not members directly and you did not supply an assignment operator, the assignment operator the compiler generated automatically just copied the pointer values, not the strings the pointers address. So if you add an assignment operator and copy constructor that copy strings instead of pointers to the Customer class, this problem should be solved.

Get ahold of Effective C++ by Scott Meyers, where the Law of Three is discussed. You might also want the C++ FAQ as well as the other C++ books by Scott Meyers, but definitely start with Effective C++.

No comments: