Skip to main content
edited tags
Link
coderodde
  • 29.8k
  • 14
  • 77
  • 194
Tweeted twitter.com/StackCodeReview/status/1282781873547227140
Source Link

C++ Dynamic Array Class Testing

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);
*/