I'm creating a basic Dynamic Array class in C++, and I'd like to know if there are any bugs/memory leaks I haven't noticed yet.
dyn_arr.h :
#ifndef DYN_ARR_H_INCLUDED
#define DYN_ARR_H_INCLUDED
template <class T>
class DynArr
{
public:
DynArr(uint16_t startSize = 0);
~DynArr();
T& operator[](uint16_t);
const T& operator[](uint16_t) const;
T& getLast() {return elements[length - 1];}
const T& getLast() const {return elements[length - 1];}
T& append(const T&);
T& insert(const T&, uint16_t);
bool kickoutLast();
bool remove(uint16_t);
uint16_t getLength() const {return length;}
uint16_t getAllocated() const {return allocated;}
private:
static const uint8_t minAllocate;
uint16_t allocated;
uint16_t length;
T* elements;
void copyElements(T*, T*);
void transfer(T*);
};
#include "dyn_arr.cpp"
#endif // DYN_ARR_H_INCLUDED
dyn_arr.cpp :
template <class T>
const uint8_t DynArr<T>::minAllocate = 4;
template <class T>
DynArr<T>::DynArr(uint16_t startSize):
allocated(0), length(0)
{
do
{
allocated += minAllocate;
}while(allocated < startSize);
elements = new T[allocated];
}
template <class T>
DynArr<T>::~DynArr()
{
if(length > 0) delete [] elements;
}
template <class T>
T& DynArr<T>::append(const T& t)
{
if(length + 1 > allocated && allocated + minAllocate <= std::numeric_limits<int16_t>::max())
{
transfer(new T[allocated += minAllocate]);
}
return elements[length++] = t;
}
template <class T>
bool DynArr<T>::kickoutLast()
{
if(length - 1 > 0)
{
--length;
if(allocated - length == minAllocate)
{
transfer(new T[allocated -= minAllocate]);
}
return true;
} else if(length - 1 == 0)
{
delete [] elements;
length = allocated = 0;
return true;
} else
{
return false;
}
}
template <class T>
T& DynArr<T>::operator[](uint16_t i)
{
if(i < length)
return elements[i];
else return elements[length - 1];
}
template <class T>
const T& DynArr<T>::operator[](uint16_t i) const
{
if(i < length)
return elements[i];
else return elements[length - 1];
}
template <class T>
T& DynArr<T>::insert(const T& t, uint16_t in)
{
if(length + 1 > allocated && allocated + minAllocate <= std::numeric_limits<int16_t>::max())
{
transfer(new T[allocated += minAllocate]);
}
for(uint16_t i = length; i > in; --i)
{
elements[i] = elements[i - 1];
}
++length;
return elements[in] = t;
}
template <class T>
bool DynArr<T>::remove(uint16_t rm)
{
if(length - 1 > 0)
{
--length;
for(uint16_t i = rm; i < length; ++i)
{
elements[i] = elements[i + 1];
}
if(allocated - length == minAllocate)
{
transfer(new T[allocated -= minAllocate]);
}
return true;
} else if(length - 1 == 0)
{
delete [] elements;
length = allocated = 0;
return true;
} else
{
return false;
}
}
template <class T>
void DynArr<T>::copyElements(T* e1, T* e2)
{
for(uint16_t i = 0; i < length; ++i)
{
e1[i] = e2[i];
}
}
template <class T>
void DynArr<T>::transfer(T* newE)
{
copyElements(newE, elements);
delete[] elements;
elements = newE;
}
code example:
#include <iostream>
#include <iomanip>
#include <thread>
#include <chrono>
#include "dyn_arr.h"
using namespace std;
template <class T>
void printArrInf(const DynArr<T>& arr, uint16_t i);
template <class T>
void printArr(const DynArr<T>& arr)
{
for(uint16_t i = 0; i < arr.getLength(); ++i)
cout << arr.getAllocated() << ", " << arr.getLength() << " : " << arr[i] << '\n';
cout << '\n';
}
int main()
{
DynArr<int> arr;
arr.append(1);
arr.append(2);
arr.append(3);
arr.append(4);
printArr(arr);
arr.insert(9, 1);
arr.remove(0);
arr.kickoutLast();
printArr(arr);
return 0;
}
/*
arr.append(1);
arr.append(2);
arr.append(3);
//arr.insert(9, 1) = 10;
for(uint16_t i = 0; i < arr.getLength(); ++i)
printArrInf(arr, i);
cout << '\n';
arr.append(4);
arr.append(5);
for(uint16_t i = 0; i < arr.getLength(); ++i)
printArrInf(arr, i);
cout << '\n';
arr.kickoutLast();
for(uint16_t i = 0; i < arr.getLength(); ++i)
printArrInf(arr, i);
cout << '\n';
arr.append(9);
for(uint16_t i = 0; i < arr.getLength(); ++i)
printArrInf(arr, i);
*/