-
Possible Heap Corruption
Hi all, so I've run into a bit of a problem with my code. It's about dynamically allocating arrays. The code works, however, one of my deletes actually causes the error " Windows has triggered a breakpoint. This may be due to corruption of the heap which indicates a bug....yada yada yada." Most indistinct and annoying thing every.
The problem happens at line 165, which is delete [] temp;. If I comment out the line, it works, 100% fine, however, I'm pretty sure I'm causing a memory leak if I do. Any ideas of what is actually happening here? I've kind of exhausted all my ideas.
Quick clarification, the delete i'm talking about is happening in the insertAt function. The similar code, in the push_back function works correctly.
Code:
// Filename: ArrayD.cpp
// The implementation file for the class class ArrayD.
/*****************************************
Complete a class that dynamically allocates arrays.
*****************************************/
#include "arrayd.h"
#include <iostream>
#include <cassert>
using namespace std;
ArrayD::ArrayD(int initCapacity) :capacity(initCapacity), used(0)
{
assert(initCapacity > 0);
a = new double[capacity];
}
ArrayD::ArrayD(const ArrayD& adObject)
:capacity(adObject.getCapacity( )), used(adObject.size( ))
{
a = new double[capacity];
for (int i =0; i < used; i++)
a[i] = adObject.a[i];
}
ArrayD::~ArrayD( )
{
delete [] a;
}
// Mutator version of operator[] (to be used on the LHS of an assignment)
double& ArrayD::operator[](int index)
{
// First check the value of the parameter 'index' for validity.
assert(index >= 0 && index < used);
// If it's valid, return the element at that index.
return a[index];
}
// Const version of operator[] (to be evaluated only)
double ArrayD::operator[](int index) const
{
assert(index >= 0 && index < used);
return a[index];
}
ArrayD& ArrayD::operator=(const ArrayD& rightSide)
{
if (this != &rightSide)
{
if (capacity != rightSide.capacity)
{
delete [] a;
a = new double[rightSide.capacity];
}
capacity = rightSide.capacity;
used = rightSide.used;
for (int i = 0; i < used; i++)
a[i] = rightSide.a[i];
}
return *this;
}
void ArrayD::pop_back()
{
// Only if the array is not empty.
// Simply decrement used.
if (!empty())
--used;
}
bool ArrayD::contains(double element) const
{
for(int i = 0; i < this->used; i++) // run through the array, from 0 to a[used-1]
{
if(this->a[i] == element)
{
return true;
}
}
return false;
}
void ArrayD::print() const
{
cout << "[";
if (this->used > 0) // check that there is any used.
{
for(int i = 0; i < (this->used -1 ); i++) //// run through the array, from 0 to a[used-2]
{
cout << this->a[i] << ",";
}
cout << this->a[this->used-1] << "]"; // used -1 is separate because it needs slightly different formatting.
}
else
{
cout <<"]";
}
}
void ArrayD::push_back(double element)
{
this->used++;
if (this->used > this->capacity) // check if we need a new array
{
//create a new one with 2 times the capacity of the previous
this->capacity *= 2;
double *temp = this->a;
this->a = new double[capacity];
// set the temp to hold the information from the first
for(int i = 0; i < this->used; i++)
{
this->a[i] = temp[i];
}
//set the element
this->a[used-1] = element;
//delete the old array
delete [] temp;
}
else // else just set the element
{
this->a[used-1] = element;
}
}
void ArrayD::insertAt(int position, double element)
{
//make sure the position is legal
if ((position < this->capacity) && (position > -1))
{
this->used++;
// check if we need a bigger array
if (this->used > this->capacity)
{
//create a 2* bigger array
this->capacity *= 2;
double *temp = this->a;
this->a = new double[capacity];
//set the temp array to the old
for(int i = 0; i < this->used; i++)
{
this->a[i] = temp[i];
}
//delete the original
// why does this delete break?
// runs fine without it, most likely has a memory leak.
delete [] temp;
}
// move all the information over if necessary
for( int i = this->used; i > position; i--)
{
this->a[i] = this->a[i-1];
}
//set the element at the position.
this->a[position] = element;
}
}
void ArrayD::deteteAt(int position)
{
if((position < this->used) && ( position > -1))
{
for(int i = position; i < used; i++)
{
this->a[i] = this->a[i+1];
}
this->used--;
}
}
-
Code:
for( int i = this->used; i > position; i--)
this could cause out of bounds access when used == capacity and you are assigning to a[i]
this will cause heap corruption...
-
Wow, good call. Feel kinda dumb that I didn't see that after staring at it for so long. Thank you for the help.