Debug assertion failed: _BLOCK_TYPE_IS_VALID(phead->nBlockUse)

Hi All,
I'm new in C++ and I have a problem which I don't seem to be able to solve. The problem seems to be caused by the destructor. When I debug the program I get the message:

Debug Assertion Failed!

File: dbgdel.cpp
line: 52

Expression: _BLOCK_TYPE_IS_VALID(phead->nBlockUse)

I also get an error message in operator= when I use the delete [] temparray; statement.

Debug error!

Heap corruption Detected:
after normal block(#185) at 0x00357440

I hope anybody can help me understand what is going on with my code.
thank you,
CH

// IntArray.h

#ifndef _INTARRAY_H
#define _INTARRAY_H

#include <string>
using namespace std;

class IntArray {
private:
int lowvalue, highvalue, size;
int* temparray;
string st;
public:
IntArray();
IntArray(int n1);
IntArray(int n1, int n2);
IntArray(const IntArray&);

void setName(string s);
int high();
int low();
int arraySize(IntArray ia);

friend ostream& operator<<(ostream& os, const IntArray& ia);
IntArray operator+(IntArray& ia);
IntArray& operator+=(IntArray& ia);
int& operator[](int i);
IntArray& operator=(const IntArray&);
int operator==(IntArray& ia);
int operator!=(IntArray& ia);
~IntArray();
};

#endif

// IntArray.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <stdlib.h>
#include "intarray.h"

using namespace std;
extern ofstream output;

IntArray::IntArray(){
lowvalue = 0;
highvalue = 9;
temparray = new int[highvalue + 1];
}

IntArray::IntArray(int n1){
lowvalue = 0;
highvalue = n1 - 1;
temparray = new int[n1];
}

IntArray::IntArray(int n1, int n2){
if(n1 <= n2){
lowvalue = n1;
highvalue = n2;
temparray = new int[n2 - n1 + 1];
}
else {//reverses the indexes if lowvalue > highvalue
cout<<"Error: Illegal array bounds"<< endl;
lowvalue = n2;
highvalue = n1;
temparray = new int[n1 - n2 + 1];
}
}

IntArray::IntArray(const IntArray& ia){
lowvalue = ia.lowvalue;
highvalue = ia.highvalue;
temparray = ia.temparray;
}

void IntArray::setName(string s){ st = s;}

int IntArray::high(){ return highvalue;}

int IntArray::low(){ return lowvalue;}

int IntArray::arraySize(IntArray ia){
size = (ia.highvalue - ia.lowvalue) + 1;
return size;
}

ostream& operator<<(ostream& os, const IntArray& ia){
for (int j = ia.lowvalue; j <= ia.highvalue; j++)
os << ia.st << "[" << j << "] = " << ia.temparray[j] << ", ";
return os;
}

IntArray IntArray::operator+(IntArray& ia){
int num = ia.highvalue - ia.lowvalue;
IntArray temp(num + 1);
for(int i = 0; i < num + 1; i++)
temp[i] = temparray[lowvalue++] + ia.temparray[ia.lowvalue++];
return temp;
}

IntArray& IntArray::operator+=(IntArray& ia){
for(int i = lowvalue; i <= highvalue; i++)
temparray[i] += ia.temparray[ia.lowvalue++];

return *this;
}

int& IntArray::operator[](int i){
if ( i > highvalue) {
cout << "Error: subscript out of bounds." << endl;
return temparray[i] = 0;
}
else
return temparray[i];
}

IntArray& IntArray::operator=(const IntArray& ia){
if(highvalue - lowvalue == ia.highvalue - ia.lowvalue) {
if (this != &ia){
//delete [] temparray;//I know I should be using this statement here but I get an error
temparray = new int[highvalue - lowvalue + 1];
int index = ia.lowvalue;
for(int i = lowvalue; i <= highvalue; i++)
temparray[i] = ia.temparray[index++];
}
return *this;
}
else cout << "Error: length mismatch." << endl;
return *this;
}

int IntArray::operator==(IntArray& ia){
if(size == ia.size && temparray == ia.temparray){
return 1;
}
else return 0;
}

int IntArray::operator!=(IntArray& ia){
if(size != ia.size || temparray != ia.temparray){
return 1;
}
else return 0;
}

IntArray::~IntArray(){
delete [] temparray;
}
[4568 byte] By [CarlH] at [2007-11-20 11:53:00]
# 1 Re: Debug assertion failed: _BLOCK_TYPE_IS_VALID(phead->nBlockUse)
Please use Code Tags when posting lengthy code sections like this. It's difficult to work through your code precisely but I noticed that temparray is being deleted in 2 places - one where you indicated; and then again in the destructor for IntArray. It's only a guess but I wonder if IntArray is somehow going out of scope? Try temporarily commenting out the deletion in IntArray's d'tor and see if that cures the problem. If so, it might lead you to find the cause. However, here's one definite possibility...

In one of your constructors you have this statement:-

temparray = ia.temparray;Since temparray is a pointer, if ia later goes out of scope, both temparray pointers will then become invalid. You probably need to copy the data into a new array - not simply copy the old array's address to a new pointer.
John E at 2007-11-11 4:02:31 >
# 2 Re: Debug assertion failed: _BLOCK_TYPE_IS_VALID(phead->nBlockUse)
Hi All,
I'm new in C++ and I have a problem which I don't seem to be able to solve. The problem seems to be caused by the destructor.You have *many* problems with the code.

IntArray::IntArray(const IntArray& ia){
lowvalue = ia.lowvalue;
highvalue = ia.highvalue;
temparray = ia.temparray;
}
This does not copy the data correctly. All you're doing is assigning the pointer. That will not work. You need to actually create another array and copy the data from ia to the new array.

The bottom line is this: When you make another copy of the IntArray object, the pointer member must have seperate data than the passed-in IntArray object. You are not doing this, all you're doing is copying the pointer member which is totally wrong.

This very simple main() program totally breaks your code:

int main()
{
IntArray a1;
IntArray a2 = a1;
} // error here.

Since you have Visual C++, why not step through the code for this simple main() program? You will see exactly what the problem is -- you have two pointers at the time of destruction that are pointing to the same place. You then attempt to call delete[] on the same pointer twice.

That's why when you create copies of classes like IntArray, you actually must create a "true" copy -- the pointer member must be pointing to its seperate copy, not share it with other objects (unless you create a reference counting scheme to your IntArray class).

Another point is that you have classes such as std::vector that does everything your IntArray class does, and without bugs. Is this a classroom exercise?

Other things that are bad with your code:

int IntArray::operator==(IntArray& ia){
if(size == ia.size && temparray == ia.temparray){
return 1;
}
else return 0;
}

int IntArray::operator!=(IntArray& ia){
if(size != ia.size || temparray != ia.temparray){
return 1;
}
else return 0;
}

There is no need for operator != to be coded this way. The proper way to code operator != is in terms of operator ==, and also, operator != and operator == should be returning bool, not int.

bool IntArray::operator==(IntArray& ia){
if(size == ia.size && temparray == ia.temparray){
return true;
}
return false;
}

int IntArray::operator!=(IntArray& ia){
return !(*this == ia);
}

This ensures that you do not make a mistake. Since != is the opposite of ==, then the error-free way of coding != is to just call == and whatever the converse of that result is, then that is the answer. No need to code the whole thing over again.

Regards,

Paul McKenzie
Paul McKenzie at 2007-11-11 4:03:31 >