problem with delete[]

Hello! I have a project for my university, and I am having problem:
1
2
3
4
5
6
7
"Windows has triggered a breakpoint in polynome v0.0.0.0.exe.

This may be due to a corruption of the heap, which indicates a bug in polynome v0.0.0.0.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while polynome v0.0.0.0.exe has focus.

The output window may have more diagnostic information."

after debugging step by step I have found that the error relies here:
1
2
3
4
5
6
polynome::~polynome()
{ //p's length is 11 here
  //when p was of length 1 this code worked without error
	cout<<"~:   "<<*this<<endl; //I have created this line to test if *this is as expected: it is
	delete []p;   //here is the error
}

this is the definition of class polynome:
1
2
3
4
5
6
class polynome
{	
        double *p;
	unsigned d;
...  //declaration of methods
};

this is the method calling the destructor (the one with the problem)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
polynome polynome::operator+=(const char* const s)
{polynome p2(s);
	if(d>=p2.d)
		for(int i=0;i<=p2.d;i++)
			p[i]+=p2.p[i];
	if(d<p2.d)
	{polynome p3(*this);
		operator=(p2);
		for(int i=0;i<=p3.d;i++)
			p[i]+=p3.p[i];
	}
	//from the debugging all is as expected here
	return *this;  //after here the first destructor cause the problem
}

Merry Christmas to you all.
if you want to see any other method I'll provide it
http://www.cplusplus.com/forum/general/112111/
probably a double delete because a bad copy constructor or assignment operator.
I don't have any unexpected warning.
and I don't think it is a double delete:
this is the copy constructor:
1
2
3
4
5
6
7
polynome::polynome(const polynome &p2)
{
	d=p2.d;
	p=new double[d+1];
	for(int i=0;i<=int(d);i++)
		p[i]=p2.p[i];
}

the assignement operator:
1
2
3
4
5
6
7
8
9
10
11
12
polynome polynome::operator=(const polynome &p2)
{
	if(d!=p2.d)
	{
		d=p2.d;
		delete []p;
		p=new double[d];
	}
	for(int i=0;i<=int(d);i++)
		p[i]=p2.p[i];
	return *this;
}
I don't know if this would help but the problem is when it tries to destruct p2 of the operator+= where the program enters in the second if:if(d<p2.d)
Last edited on
operator+= should return a reference to polynome.

Sometimes you use d + 1 and others just d when you are allocating space. Also, operator= has trouble when p2 has a greater d than the original.
no way to debug without the full code, but I will check these things
- all for loops, i=0; i<= ....
are u sure it is <= or < -- double check?
- in the for loops using int i --- should they be "unsigned int i"
- some times the values can be such that int can overflow, vs unsigned int..
@LowestOne
Thank you the answer was that I used d instead of d+1
but for the idea that operator+= should return a reference I don't think so (please correct me if I was wrong and tell me why)

@ashishkumar
-no it is <= because d is the degree of the polynomial and I should see the coefficient of the monomial of the degree d
-yes probably but I already corrected it by putting:i<=int(d). (I did it after posting it)
-Probably to correct this I should make it like this:
1
2
3
4
5
6
class polynome
{	
        double *p;
	int d;
...  //declaration of methods
};

because sometimes (in the operator<< for cout), I must use int because it is a reverse for loop and it stops when i becomes negative
anyway thanks for helping me LowestOne nailed the problem
I'm sorry in case my English wasn't correct.
Both += and = operators return references. This is the return from the assignment, it's not obvious. Consider istream::get(), which returns a character.
1
2
3
char ch;
while ( ( ch = std::cin.get() ) != 'Q' )
  std::cout << "You hit: " << ch << std::endl;

Why should we copy ch when we assign it the result of get()?

The + operator does return a new object because a = b + c can not modify b or c. With the addition, we create a temporary object, and then assign it to a. a = a + b is doing more than it needs to because that temp is still created.

Check it out:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

#include <iostream>

void print( const char* str ){ std::cout << str << std::endl; }

struct Number
{
  int value;

  Number( void )               :value(0)          { print("Default Ctor"   );}
  Number( const int v )        :value(v)          { print("Assignment Ctor");}
  Number( const Number& other ):value(other.value){ print("Copy Ctor"      );}

  Number& operator=( const Number& other )
  {
    print( "Assignment" );
    this->value = other.value;
    return *this;
  }

  Number& operator+=( const Number& other )
  {
    print( "Compound assignment" );
    this->value += other.value;
    return *this;
  }

  Number operator+( const Number& other )
  {
    print( "Addition" );
    return Number( this->value + other.value );
    // also calls assignment ctor
    // return this->value + other.value;
  }
};

int main( void )
{
  Number a(1);  // -> Assignment Ctor
  Number b = 2; // -> Assignment Ctor
  a = a + b;    // -> Addition, Assignment Ctor, Assignment
  a += b;       // -> Compound Assignment
  return 0;
}


This is the same reason it is better to do ++i than i++. The difference is that ++i can return a reference to i:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Number& operator++( void )
{
  ++this->value;
  return *this;
}

Number operator++( int ) // nevermind the int, just makes it a postfix operator
{ 
  Number temp( *this );
  ++this->value;
  return temp;
}

// ...

Number a(1);

if ( a++ == 1 ) // increment needs to be visible after the comparison
if ( ++a == 3 ) // increment is visible before comparison 
Last edited on
You've got it backwards
1
2
Number operator++( int ); //postfix
Number& operator++( void ); //prefix 


> The difference is that ++i can return a reference to i:
++i does not need a temporary.
Last edited on
^ ah, thanks. I've updated the post to reflect that.
Last edited on
and Number operator+( const Number& other ) should be Number operator+( const Number& other )const...

and assignment operator must check for self-assignment. if (this == &other) return *this;

Thank you all
Topic archived. No new replies allowed.