Search code examples
c++glibc

glibc error after desired output


I'm sorry if the following code is long, but I don't know what is relevant to the problem and what is not.

#include <iostream>
#include <cmath>
#include <cstdio>

using namespace std;

template <class T>
class Array;

template <typename T>
ostream& operator<< (ostream &output, Array<T> &obj);

template <class T>
class Array {
private:
  int capacity;
public:
  T *arr;

  Array();
  Array(int);
  ~Array();

  void Erase();
  T& operator[](int);
  friend ostream& operator<< <>(ostream &output, Array &obj);
  int GetLength();

};

/* Constructors and Destructors */

template <class T>
Array<T>::Array() {
   capacity = 0;
   arr = new T [capacity];
}

template <class T>
Array<T>::Array(int n) {
  capacity = n;
  arr = new T [capacity];
}

template <class T>
Array<T>::~Array() {
  delete [] arr;
}

/* End of Constructors and Destructors */

/* Member Functions */

template <class T>
void Array<T>::Erase() {
  delete [] arr;
  capacity = 0;
  arr = new T [capacity];
}

template <class T>
int Array<T>::GetLength() {
   return capacity;
}

/* End of Member Functions */

/* Overloaded Operators */

template <class T>
T& Array<T>::operator[](int index) {
  /*if (index < 0 || index >= capacity)
    cout << "Index out of range!" << endl;

  else */
    return arr[index];

 }

template <class T>
ostream& operator<<(ostream &output, Array<T> &obj) {
  for (int i = 0; i < obj.capacity - 1; ++i)
    output << "Array[" << i << "] = " << obj[i] << ", ";

  output << "Array[" << obj.capacity - 1 << "] = " << obj[obj.capacity - 1];

  return output;
}

/* End of Overloaded Operators */

/* Non-member Functions */

template <typename T>
void BubbleSort(Array<T> &t);

template <typename T>
T Sum(Array<T> &t);

template <typename T>
T Average(Array<T> &t);

template <typename T, typename M>
bool Equal(Array<T> &t, Array<M> &m);

template <typename T>
bool Equal(Array<T> &t, Array<double> &d);

/* End of Non-Member Functions */

/* Main Function */

int main()
{
  int n;
  double r;

  cin>>r;
  cin>>n;

  Array<int> anArray(n);
  Array<double> adArray(n);
  Array<int> intArray2(n);

  for (int nCount = 0; nCount < n; nCount++)
  {

      cin>>anArray[nCount];
      adArray[nCount] = anArray[nCount] + r;
  }

  BubbleSort(anArray);

  intArray2 = anArray;

  cout<<"The arrays: "<<endl;
  cout<<anArray;
  cout<<endl<<"and "<<endl;
  cout<<intArray2;
  cout<<((Equal(anArray,intArray2))?" ARE":" ARE NOT")<<" same!"<<endl;
  cout<<"The Average of the array adArray is: "<<Average(adArray)<<endl;

 cout<<"The arrays: "<<endl;
 cout<<anArray;
 cout<<endl<<"and "<<endl;
 cout<<adArray;
 cout<<((Equal(anArray,adArray))?" ARE":" ARE NOT")<<" same!";

  return 0;
}

/* End of Main */

/* Non-Member Function implementation */

template <typename T>
void BubbleSort(Array<T> &t) {
  int j;
  bool flag = true;

  while (flag) {
    flag = false;

    for (j = 0; j < t.GetLength() - 1; ++j) {
      if (t[j] > t[j + 1]) {
         swap(t[j], t[j + 1]);
         flag = true;
      }
    }
  }

  return;
}


template <typename T>
T Sum(Array<T> &t) {
  T sum = 0;

  for (int i = 0; i < t.GetLength(); ++i)
    sum += t.arr[i];

  return sum;
}

template <typename T>
T Average(Array<T> &t) {
  return ( Sum(t)  / t.GetLength() );
}

template <typename T, typename M>
bool Equal(Array<T> &t, Array<M> &m) {
  if ( t.GetLength() != m.GetLength() )
    return false;

  bool flag = true;

  for (int i = 0; i < t.GetLength(); ++i) {
    if ( t.arr[i] != m.arr[i] ) {
      flag = false;
      break;
    }
  }

  return flag;
}

template <typename T>
bool Equal(Array<T> &t, Array<double> &d) {
  if ( t.GetLength() != d.GetLength())
    return false;

  bool flag = true;

  for (int i = 0; i < t.GetLength(); ++i) {
     if ( abs(t.arr[i] - d.arr[i]) > 0.1 ) {
       flag = false;
       break;
     }
    if ( abs(Average(t) - Average(d)) > 0.5 ) {
      flag = false;
      break;
    }
  }

  return flag;
}
/* End of Non-Member Function Implementation */

When i run this program in Code Blocks, there is no error and it produces the desired output. However, when I use it on our college's browser platform for writing programs (something like CodeSculptor for C++), after the desired output, it gives the following error:

***glibc detected*** double free or corruption (fasttop)

and then proceeds with a Memory map (it's quite long, so I'm not sure if I should post it or not).

My question is, if there is a problem with the code, then why doesn't it show when I run the program in CodeBlocks? In that case, what is the problem with the code? Also, when running the program in the browser platform, the error message is after the desired output. Does this mean there is something wrong with the program termination?

Thank you for your time.


Solution

  • You aren't implementing the rule of three.

    This line intArray2 = anArray;, as you haven't provided the copy assignment operator, will use the built-in one, which will blindly copy each member of your object.

    Now two object's T *arr point to the same place, and when the destructors gets called.. well, you get the idea... UB. glibc is really your friend here.

    It also caused a memory leak (the previous arr pointer was simply overwritten), but compared to the double-freeing, that's a minor issue.