Thread: Possible Heap Corruption

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    2

    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--;
       }
    
    }
    Last edited by Michael5978; 04-06-2010 at 03:40 PM. Reason: Clarification

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    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...
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    Apr 2010
    Posts
    2
    Wow, good call. Feel kinda dumb that I didn't see that after staring at it for so long. Thank you for the help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why is this free corruption the heap?
    By braden87 in forum C Programming
    Replies: 1
    Last Post: 01-24-2010, 01:16 PM
  2. Heap corruption detected. What does it mean?
    By franziss in forum C++ Programming
    Replies: 17
    Last Post: 07-23-2008, 02:50 AM
  3. Heap corruption using zlib inflate
    By The Wazaa in forum C++ Programming
    Replies: 0
    Last Post: 03-29-2007, 12:43 PM
  4. Heap corruption errors
    By VirtualAce in forum C++ Programming
    Replies: 0
    Last Post: 07-15-2006, 04:46 PM
  5. heap question
    By mackol in forum C Programming
    Replies: 1
    Last Post: 11-30-2002, 05:03 AM