Mega Code Archive

 
Categories / C++ / Class
 

A generic safe-array class that prevents array boundary errors

#include <iostream> #include <new> #include <cstdlib> using namespace std; template <class T, int len> class dyn_safe_array {   T *aptr;     int length; public:   dyn_safe_array();   // copy constructor.   dyn_safe_array(const dyn_safe_array &obj);   // Release the allocated memory when a dyn_safe_array object goes out of scope.   ~dyn_safe_array() {      delete [] aptr;   }   // Overload assignment.   dyn_safe_array &operator=(const dyn_safe_array<T,len> &rh_op);   // Use the subscripting operator to access elements in the safe array.   T &operator[](int i);      // Return the size of the array.   int getlen() { return length; } }; // constructor. template <class T, int len> dyn_safe_array<T, len>::dyn_safe_array() {   try {     aptr = new T[len];   } catch(bad_alloc ba) {     cout << "Can't allocate array.\n";     // Take appropriate action here. This is just     // a placeholder response.     exit(1);   }   // Initialize the array elements to their default value.   for(int i=0; i < len; ++i) aptr[i] = T();   length = len; } // copy constructor. template <class T, int len> dyn_safe_array<T, len>::dyn_safe_array(const dyn_safe_array &obj) {   cout << "Using dyn_safe_array's copy constructor to make a copy.\n";   try {     aptr = new T[obj.length];   } catch(bad_alloc ba) {     cout << "Can't allocate array.\n";     exit(1);   }   length = obj.length;   // Copy contents of the array.   for(int i=0; i < length; ++i)     aptr[i] = obj.aptr[i]; } // Overload assignment so that a copy of the array is made. // The copy is stored in an allocated memory that is separate // from that used by the right-hand operand. template<class T, int len> dyn_safe_array<T, len> & dyn_safe_array<T, len>::operator=(const dyn_safe_array<T, len> &rh_op) {  // If necessary, release the memory currently used by the object.  if(aptr && (length != rh_op.length)) {    // Delete the previously allocated memory.    delete aptr;    try {      // Allocate an array of the same size as the one used by rh_op.      aptr = new T[rh_op.length];    } catch(bad_alloc ba) {      // Take appropriate action here. This is just a placeholder response.      cout << "Can't allocate array.\n";      exit(1);    }  }  length = rh_op.length;  // Copy contents of the array.  for(int i=0; i < length; ++i)    aptr[i] = rh_op.aptr[i];    return *this; } template <class T, int len> T &dyn_safe_array<T, len>::operator[](int i) {   if(i < 0 || i > length) {     cout << "\nIndex value of " << i << " is out-of-bounds.\n";     exit(1);   }   return aptr[i]; } template <class T, int len> dyn_safe_array<T, len> f(dyn_safe_array<T, len> x) {   cout << "f() is returning a copy of x.\n";   return x; } class myclass { public:   int x;   myclass(int i) { x = i; };   myclass() { x = -1; } }; int main() {   // Use the integer array.   dyn_safe_array<int, 5> i_ar;   for(int i=0; i < i_ar.getlen(); ++i) i_ar[i] = i;   cout << "Contents of i_ar: ";   for(int i=0; i < i_ar.getlen(); ++i) cout << i_ar[i] << " ";   cout << "\n\n";   dyn_safe_array<int, 5> i_ar2 = i_ar;   for(int i=0; i < i_ar2.getlen(); ++i) cout << i_ar2[i] << " ";   dyn_safe_array<int, 5> i_ar3;   for(int i=0; i < i_ar3.getlen(); ++i) cout << i_ar3[i] << " ";   cout <<"\n\n";   i_ar3 = f(i_ar);   for(int i=0; i < i_ar3.getlen(); ++i)  cout << i_ar3[i] << " ";   cout << "\n\n";   dyn_safe_array<myclass, 3> mc_ar;   cout << "Original contents of mc_ar: ";   for(int i=0; i < mc_ar.getlen(); ++i) cout << mc_ar[i].x << " ";   cout << endl;   mc_ar[0].x = 9;   mc_ar[1].x = 8;   mc_ar[2].x = 7;   for(int i=0; i < mc_ar.getlen(); ++i) cout << mc_ar[i].x << " ";   cout << "\n\n";   cout << "   mc_ar2 = f(mc_ar);\n\n";   dyn_safe_array<myclass, 3> mc_ar2;   mc_ar2 = f(mc_ar);   cout << "Contents of mc_ar2 after receiving f(mc_ar): ";   for(int i=0; i < mc_ar2.getlen(); ++i) cout << mc_ar2[i].x << " ";   cout << endl;   return 0; }