HEAP CORRUPTION DETECTED : after normal block () - c++

So, I've defined template class and then i tried to overload some operators.
template <typename T> class Set
{
public:
Set(void);
Set(Set&);
~Set(void);
bool contains(T elem);
bool add(T elem);
bool remove(T elem);
bool add(T* tab, int size);
T* getSet();
int size();
Set<T> &operator+(Set<T> &snd);
Set<T> &operator-(Set<T> &snd);
private:
T *elements;
int numOfElem;
};
When I try to add element to the Set by add method everything works fine.
template<typename T>
bool Set<T>::add(T elem)
{
bool found = false;
for(int i =0; !found && i<numOfElem; i++){
if(elem == elements[i]) found = true;
}
if( !found ){
numOfElem++;
T* tmp = new T[numOfElem];
for(int i =0; i<numOfElem-1; i++){
tmp[i] = elements[i];
}
tmp[numOfElem-1] = elem;
delete[] elements;
elements = tmp;
}
return !found;
}
template<typename T>
bool Set<T>::add(T* myArray, int size)
{
bool result = false;
for(int i =0; i<size; i++){
add(myArray[i]);
}
return result;
}
template<typename T>
Set<T>& Set<T>::operator+(Set<T> &snd)
{
Set *temp = new Set(*this);
temp->add(snd.getSet(), snd.size());
return *temp;
}
template<typename T>
void Set<T>::operator=(Set<T> &snd)
{
numOfElem = snd.numOfElem;
elements = new T[numOfElem];
for(int i =0; i < numOfElem; i++){
elements[i] = snd.elements[i];
}
}
template<typename T>
int Set<T>::size()
{
return numOfElem;
}
template<typename T>
T* Set<T>::getSet()
{
return elements;
}
template<typename T>
Set<T>::Set()
{
numOfElem = 0;
elements = nullptr;
}
template<typename T>
Set<T>::Set(Set& old)
{
numOfElem = old.numOfElem;
elements = new T(numOfElem);
for(int i = 0; i< numOfElem; i++){
elements[i] = old.elements[i];
}
}
template<typename T>
Set<T>::~Set()
{
numOfElem = 0;
delete[] elements;
elements = nullptr;
}
But if I use + operator instead (adding two separate sets) the error occurs while trying to delete the array (15 Line). Any ideas?
int main(){
Set <char> set1, set2, set3;
char tab[] = {'a','d','f','g'} ;
set1.add(tab, 4);
char tab2[] = {'a','d','x','y','z'} ;
set2.add(tab2,5);
set3= set1+set2;
}

You have a mistake in your copy constructor:
elements = new T(numOfElem);
It should be
elements = new T[numOfElem];
By writing new T(numOfElem); you allocate only one variable with its value initialized to numOfEllem.
Use a std::vector instead of the array and you will avoid such problems.
Your code is also leaking a memory in the addition operator:
template<typename T>
Set<T>& Set<T>::operator+(Set<T> &snd)
{
Set *temp = new Set(*this);
temp->add(snd.getSet(), snd.size());
return *temp;
}
You are allocating a memory and you never delete it so if you call that function too often you program may run out of its virtual memory and will crash with the uncaught std::bad_alloc exception. Change the function to this:
template<typename T>
Set<T> Set<T>::operator+(Set<T> &snd)
{
Set temp(*this);
temp.add(snd.getSet(), snd.size());
return temp;
}

Related

Problem freeing memory (subject Template)

Set.h
#ifndef Set_h
#define Set_h
#include <iostream>
using namespace::std;
template <class T>
class Set {
T* group;
int size_group;
public:
Set():group(NULL),size_group(0){};
Set(T*,int);
Set(const Set<T>&);
~Set();
bool isThere(const T&)const;
void getType()const;
Set<T>& operator =(const Set<T>&);
bool operator ==(const Set<T>&) const;
void operator +=(const T);
void operator -=(const T&);
Set<T>& operator +(Set<T>&);
Set<T>& operator -(const Set<T>&);
bool operator >(const Set<T>&)const;
friend ostream& operator <<(ostream&,const Set<T>&);
};
//Realizations
template <class T>
Set<T>::Set(T* gro,int size):group(gro),size_group(size){}
template <class T>
Set<T>::Set(const Set<T>& obj){ // c'Ctor (copy)
this->size_group = obj.size_group;
this->group = new T[this->size_group];
for (int i = 0; i < size_group; i++) {
group[i] = obj.group[i];
}
}
template <class T>
void Set<T>::getType() const{
cout << "The type is: " << typeid(group).name() << endl;
}
template <class T>
Set<T>& Set<T>::operator = (const Set<T>& obj){
this->size_group = obj.size_group;
this->group = new T[size_group];
for (int i = 0; i < size_group; i++) {
this->group[i] = obj.group[i];
}
return *this;
}
template <class T>
bool Set<T>::operator==(const Set<T>& obj) const{
int count = 0;
T temp;
if(this->size_group != obj.size_group)
return false;
for (int i = 0; this->size_group; i++) {
temp = this->group[i];
count = 0;
for (int j = 0; j < obj.size_group; j++) {
if(temp == obj.group[j])
count++;
}
if(count != 1)
return false;
}
return true;
}
template <class T>
void Set<T>::operator+=(const T var){
if(!isThere(var)){
T* Temp = new T[this->size_group+1];
for (int i = 0; i < this->size_group; i++)
Temp[i] = this->group[i];
Temp[size_group] = var;
delete [] this->group;
this->size_group++;
this->group = Temp;
}
}
template <class T>
Set<T>& Set<T>::operator+(Set<T>& obj){ //
if(obj.size_group > this->size_group){
for (int i = 0; i < obj.size_group; i++){
for (int j = 0 ; j < this->size_group; j++){
if(!this->isThere(obj.group[i]))
*this += obj.group[i];
}
}
return *this;
}else{
for (int i = 0; i < this->size_group; i++){
for (int j = 0 ; j < obj.size_group; j++){
if(!obj.isThere(this->group[i]))
obj += this->group[i];
}
}
return obj;
}
}
template <class T>
bool Set<T>::isThere(const T& var) const{
for (int i = 0; i < this->size_group; i++) {
if(this->group[i] == var)
return true;
}
return false;
}
template <class T>
Set<T>::~Set() {
delete [] group;
}
#endif /* Set_h */
Main:
#include "Set.h"
int main() {
int arr[] = {3,7,8,1};
int arr2[] = {1,2,5};
Set<int> j(arr,4),l(arr2,3),k;
k = j + l;
}
I'm trying to merge two arrays, but my problem is with the method void Set<T>::operator+=(const T var) and this line delete [] this-> group;
I get this error:
Template & Exception (8421,0x1000dadc0) malloc: *** error for object 0x7ffeefbff400: pointer being Friday was not allocated
Template & Exception (8421,0x1000dadc0) malloc: *** set a breakpoint in malloc_error_break to debug
Your Set(T*,int) constructor is not allocating new[]'ed memory for group to point at, which means operator+= (and ~Set(), and operator=) will fail at runtime when they try to delete[] the memory that group points at, which in your example is local stack memory that main() owns and passes in to the j and l objects.
Your Set(T*,int) constructor must new[] the group array and copy the contents of the input gro array into it, similar to how your copy constructor does, eg:
template <class T>
Set<T>::Set(T* gro, int size) : group(NULL), size_group(0)
{
size_group = size;
group = new T[size];
for (int i = 0; i < size; i++) {
group[i] = gro[i];
}
}
On a side note, your operator= is leaking memory, as it does not delete[] the current group array before assigning a new group array. It should be making a temporary array, similar to how your operator+= does, eg:
template <class T>
Set<T>& Set<T>::operator=(const Set<T>& obj)
{
if (this != &obj){
T* Temp = new T[obj.size_group];
for (int i = 0; i < obj.size_group; i++)
Temp[i] = obj.group[i];
delete [] group;
group = Temp;
size_group = obj.size_group;
}
return *this;
}
Or better, use your copy constructor via the copy-swap idiom instead:
template <class T>
Set<T>& Set<T>::operator=(const Set<T>& obj)
{
if (this != &obj){
Set<T> temp(obj);
std::swap(group, temp.group);
std::swap(size_group, temp.size_group);
}
return *this;
}
Also, your operator+ is implemented all wrong. It needs to return a new Set that is the concatenation of the arrays of *this and obj, not modify obj or *this at all. As such, it needs to look more like this instead:
template <class T>
Set<T> Set<T>::operator+(const Set<T>& obj) const
{
Set<T> res(*this);
for (int i = 0; i < obj.size_group; i++) {
res += obj.group[i];
}
return res;
}

What have I missed, what cause the memory leak C++

I'm having problem understanding where my memory leak is located in my project.
The template I have built looks like this:
#pragma once
#include "IHeap.h"
#include <iostream>
using namespace std;
template <typename T>
class dHeap
{
public:
dHeap(T size);
dHeap(T size, int nr);
dHeap(const dHeap &original);
~dHeap();
dHeap<T>& operator=(const dHeap<T> &original);
void deepCopy(const dHeap &original);
void push(const T &item);
T pop();
T peek()const;
int size()const;
int getdValue()const;
void printAll()const;
void heapify(int arr[], int size, int root);
void heapSort(int arr[], int size);
private:
//T nr;
T *arrHeap;
T nrOfItems;
T capacity;
T dValue;
void expandHeap();
};
template<typename T>
inline dHeap<T>::dHeap(T size)
{
capacity = size;
arrHeap = new T[capacity + 1];
nrOfItems = 0;
dValue = size;
}
template<typename T>
inline dHeap<T>::dHeap(T size, int nr)
{
capacity = size;
arrHeap = new T[nr];
nrOfItems = 0;
dValue = size;
}
template<typename T>
inline dHeap<T>::dHeap(const dHeap &original)
{
this->deepCopy(original);
}
template<typename T>
inline dHeap<T>::~dHeap()
{
delete[] arrHeap;
}
template<typename T>
inline dHeap<T>& dHeap<T>::operator=(const dHeap<T>& original)
{
if (this != &original)
{
this->deepCopy(original);
}
return *this;
}
template<typename T>
inline void dHeap<T>::expandHeap()
{
capacity *= 2;
T *temp = new T[capacity];
for (int i = 0; i < nrOfItems; i++)
{
temp[i] = arrHeap[i];
}
delete[] arrHeap;
arrHeap = temp;
}
template<typename T>
inline void dHeap<T>::deepCopy(const dHeap &original)
{
capacity = original.capacity;
nrOfItems = original.nrOfItems;
arrHeap = new T[capacity];
dValue = original.dValue;
for (int i = 0; i < original.nrOfItems; i++)
{
this->arrHeap[i] = original.arrHeap[i];
}
}
template<typename T>
inline void dHeap<T>::push(const T &item)
{
if (nrOfItems >= capacity)
{
expandHeap();
}
arrHeap[nrOfItems] = item;
nrOfItems++;
}
template<typename T>
inline T dHeap<T>::pop()
{
int removed = arrHeap[0];
arrHeap[0] = arrHeap[nrOfItems - 1];
nrOfItems--;
return removed;
}
template<typename T>
inline T dHeap<T>::peek() const
{
return arrHeap[0];
}
template<typename T>
inline int dHeap<T>::size() const
{
return this->nrOfItems;
}
template<typename T>
inline int dHeap<T>::getdValue() const
{
return this->dValue;
}
template<typename T>
inline void dHeap<T>::printAll() const
{
for (int i = 0; i < nrOfItems; i++)
{
cout << "Heap element " << i << ". " << arrHeap[i] << endl;
}
}
template<typename T>
inline void dHeap<T>::heapSort(int arr[], int size)
{
for (int j = 0; j < size; j++)
{
// Build heap - which means rearrange array
for (int i = size / 2 - 1; i >= 0; i--)
{
heapify(arrHeap, size, i);
}
for (int i = size - 1; i >= 0; i--)
{
swap(arrHeap[0], arrHeap[i]);
heapify(arrHeap, i, 0);
}
//when re-structured heap, use pop and re-do it again until done
arr[j] = pop();
}
}
template<typename T>
inline void dHeap<T>::heapify(int arr[], int n, int root)
{
int largest = root;
int leftChild = 2 * root + 1;
int rightChild = 2 * root + 2;
// If left child is larger than root
if (leftChild < n && arr[leftChild] > arr[largest])
{
largest = leftChild;
}
// If right child is larger than largest so far
if (rightChild < n && arr[rightChild] > arr[largest])
{
largest = rightChild;
}
// If largest is not root, heapify recursivly until done
if (largest != root)
{
swap(arr[root], arr[largest]);
heapify(arr, n, largest);
}
}
I have a pointer called heapArr which I use to build up a heap. When the program terminates the destructor is called and there have I put a delete[] this->heapArr declaration to remove the pointer when program is done.
And I have also added a delete[] this->heapArr in the expand function in order to free the memory before allocation the new expanded array.
I'm not sure I explained this perfectly but the problem is that I seem to miss to remove something because I get a memory leak warning when I end the program.
What have I missed?
Memory leaks in deepCopy, where you allocate new memory without de-allocating the old.
That being said, don't allocate memory yourself. A good chunk of your code is duplicating the functionality of std::vector, so use std::vector<T> instead of T*.
(If for some reason you cannot use std::vector I would recommend you implement a replacement. Divide-and-conquer by splitting memory management from the heap logic.)

Dynamic Array - Finding Capacity

I have been looking through the std::vectors source code and looking at how it's capacity (vector.capacity()) function works, i'm not quite understanding how i would implement it into my Dynamic array source code. I would not just be returning the current container size would i. e.g dynarray.size().
,Thanks
#include <iostream>
#include <vector>
#include <iterator>
#pragma once
template<typename T>
class DynamicArrayIter
{
public:
DynamicArrayIter(T* data) : newData(data) { }
//DynamicArrayIter(const DynamicArrayIter& o); // Copy constructor
//DynamicArrayIter& operator=(const DynamicArrayIter& o); // Assignment operator
DynamicArrayIter operator++() { DynamicArrayIter i = *this;newData++; return i;}
DynamicArrayIter operator++(int junk) {newData++;return *this; }
T& operator*() {return *newData; }
bool operator==(const DynamicArrayIter& rhs) {return newData == rhs.newData; }
bool operator!=(const DynamicArrayIter& rhs) { return newData != rhs.newData;}
DynamicArrayIter<T> operator+(int _i)
{
DynamicArrayIter<T> iter = *this;
for (int i = 0; i < _i; ++i)
{
if (iter.newData) //If there's something to move onto...
++iter;
else
break;
}
return iter; //Return regardless of whether its valid...
}
private:
T* newData;
};
template<typename T>
class DynamicArray
{
public:
DynamicArray<T> operator=(const DynamicArray<T>&);//Dynamic Array equals Dynamic Array
DynamicArray();//Constructor
~DynamicArray();//Destructor
void push_back(const T&);//Push back a new element into the DynArray
void pop_back();//Pop an element off the back of the DynArray
void print();//Prints out what is in the container
bool empty();//Empty the DynArray container
void reserve(int);//Reserver a size of which the Dynarray can reach, once it reachers the limit it will increase etc.
void resize(int);//resize the Dynrray container data will be carried into the new size either cutting off eccess data or reserving space for more.
void swap(DynamicArray<T>);//Swap the contents in the Dynarray with another Dynarray containers.
void assign(size_t,T);//Assign new content to the Dynarray, replacing the current elements and changing its size accordingly
void assign(DynamicArrayIter<T>, DynamicArrayIter<T>);//Assign new content to the Dynarray, replacing the current elements and changing its size accordingly
void insert(DynamicArrayIter<T>,T);//Insert a element at a certain positon elements will be moved and adjusted accordingly
void erase(DynamicArrayIter<T>);//Erase an element at a certain postion
void erase(DynamicArrayIter<T>,DynamicArrayIter<T>);//Erase an element at a certain postion
T& at(int );// Element postion at index
T& front();//elements t postion
T& back();//elements back position
T& operator[] (int);//subscript location access
size_t capacity();//capacity of the container
size_t max_size();//max size of the vontainer
DynamicArrayIter<T> begin();//Begin on the container/DynArray - Iterator uses this to grab the begin of the Dynarray
DynamicArrayIter<T> end();//End on the container/DynArray - Iterator uses this to grab the End of the Dynarray
void clear();//Clear the whole container
int size();//Size of the current container returns sizeofarray
private:
T* myArray;//Where data is stored
int sizeofarray = 0;//size of the current container
};
template<typename T>
inline DynamicArray<T> DynamicArray<T>::operator=(const DynamicArray<T>&newDynArray)
{
myArray = new T[newDynArray.size()];
for (size_t i = 0; i < newDynArray.size(); i++)//will make the current array the size of the new one
{
myArray[i] = newDynArray.myArray[i];//Current Dynarray = the pass in Dynarray - Steps through changign each element
}
return newDynArray;//return the passed data
}
template<typename T>
inline DynamicArray<T>::DynamicArray()
{
myArray = new T[sizeofarray];//Creating a new Dynarray of size
}
template<typename T>
inline DynamicArray<T>::~DynamicArray()
{
delete[] myArray;//deleting the Dynarray
}
template<typename T>
inline void DynamicArray<T>::push_back(const T& pusheddata)
{
T *temp = myArray;//Creating a temp array with the value of the current Dynarray
myArray = new T[++sizeofarray];//Dynarray = new Dynarray of current size + 1 // Size is being incremented from this
myArray[sizeofarray - 1] = pusheddata;//Pushing the element onto the back of the Array
for (int i = 0; i < sizeofarray - 1; ++i)//It is sizearray - 1 as we dont the temp does not have the data we just pushed onto the back
{
myArray[i] = temp[i];//going through a loop putting the data from the temp we created back into the DynArray.
}
delete[] temp;//delete the temp
}
template<typename T>
inline void DynamicArray<T>::pop_back()
{
T *temp = myArray;//Creating a temp array with the value of the current Dynarray
myArray = new T[sizeofarray--];//Dynarray = new Dynarray of current size - 1 // Size is being decreased from this
for (int i = 0; i < sizeofarray; ++i)
{
myArray[i] = temp[i];//Dynarray equals the temp values
}
delete[] temp;//Delete the temp
}
template<typename T>
inline void DynamicArray<T>::print()
{
for (size_t i = 0; i < sizeofarray; i++)
{
std::cout << myArray[i] << std::endl;//Just looping through and printing the element until it hits size.
}
}
template<typename T>
inline bool DynamicArray<T>::empty()
{
if (size() == 0)
{
return true;//return true if size is 0
}
return false;//return flase if size >=1
}
template<typename T>
inline void DynamicArray<T>::reserve(int r_size)
{
sizeofarray = r_size;//size = the reserve size
}
template<typename T>
inline void DynamicArray<T>::resize(int newsize)
{
T *temp = myArray;//Creating a temp with the current Dynarray inside of it
myArray = new T[newsize];//Dynarray = a new Dynarray of size (newsize)
for (int i = 0; i < newsize; ++i)
{
myArray[i] = temp[i];//Setting the Dynarrays elements to the temps
}
for (int i = sizeofarray; i < newsize; i++)
{
myArray[i] = NULL;//Set the elements outside the size allowed to NULL
}
sizeofarray = newsize;//Size = new size
delete[] temp;//delete the temp
}
template<typename T>
inline void DynamicArray<T>::swap(DynamicArray<T> newSwap)
{
clear();//clear the current Dynarray
for (size_t i = 0; i < newSwap.sizeofarray; i++)
{
myArray[i] = newSwap.myArray[i];//Newly cleared Dynarray elements = passed in swapped data
sizeofarray++;//increment the size
}
}
template<typename T>
inline void DynamicArray<T>::assign(size_t n, T val)
{
clear();//Clear the Dynarray
myArray = new T[n];//Dynarray = new Dynarray of size_t n
for (size_t i = 0; i < n; i++)//for i < size_t n
{
myArray[i] = val;//Dynarray = val passed through
sizeofarray++;//increment the size of the Dynarray
}
}
template<typename T>
inline void DynamicArray<T>::assign(DynamicArrayIter<T> first, DynamicArrayIter<T> last)
{
int n = 0;//temp size holder
for (DynamicArrayIter<T> iter = first; iter != last; ++iter) {
n++;//increment the temp size holder
}
clear();//clear the Dynarray
myArray = new T[n];//Make a new Dynarray and its size is the temp size holders
for (DynamicArrayIter<T> newiter = first; newiter != last; ++newiter) {
myArray[sizeofarray] = *newiter;//Iterate through and set each element to the value passed in
sizeofarray++;//incremenet the size
}
}
template<typename T>
inline void DynamicArray<T>::insert(DynamicArrayIter<T> position, T val)
{
int sizeofthis = 0;//temp size holder for iter
int j = 0;//Index position // increments when position is meet
for (DynamicArrayIter<int> iter = begin(); iter != position; ++iter){
++sizeofthis;//increase the temp size holder fo riter
}
T *temp = myArray;//Create a new temp Dynarray
sizeofarray += 1;//temp size hodler + 1
myArray = new T[sizeofarray];//Dynarray = new Dynarray of temp size holder for iter
for (size_t i = 0; i < sizeofarray; i++)
{
if (i == sizeofthis)//if the for loops i = tempsize holders
{
myArray[sizeofthis] = val;//Dynarray element = val being passed in
j++;//Index pos ++
}
myArray[i + j] = temp[i];//Dynarray = Temps values // Will change when inserted pos is reached // dynamically chagne size
}
delete[] temp;//delete temp
}
template<typename T>
inline void DynamicArray<T>::erase(DynamicArrayIter<T> position)
{
int sizeofthis = 0;//temp size holder for iter
int j = 0;//index pos//increments wehn pos is met
for (DynamicArrayIter<int> iter = begin(); iter != position; ++iter) {
++sizeofthis;//increment the temp size holder
}
T *temp = myArray;//temp = current Dynarray
sizeofarray -= 1;//size decreased by 1
myArray = new T[sizeofarray];//new Dynarray of the new size
for (size_t i = 0; i < sizeofarray; i++)
{
if (i == sizeofthis)//if the loops i reaches the temp size holders value
{
myArray[sizeofthis] = myArray[sizeofthis + 1];//Dynarray at sizeoftihs = Dynarrays next element
j++;//index pos ++
}
myArray[i] = temp[i + j];//Dynarray = the temp[idexpos will be greater > 0 if i == sizeofthis]
}
delete[] temp;//delete the temp
}
template<typename T>
inline void DynamicArray<T>::erase(DynamicArrayIter<T> first, DynamicArrayIter<T> last)
{
int sizeofthis = 0;
for (DynamicArrayIter<int> iter = first; iter != last; ++iter) {
++sizeofthis;
}
T *temp = myArray;
sizeofarray = sizeofarray - sizeofthis - 1;
myArray = new T[sizeofarray];
for (size_t i = 0; i < sizeofarray; i++)
{
if (i < sizeofthis)
{
myArray[sizeofthis - 1 + i] =NULL;
}
myArray[i] = temp[i];
}
delete[] temp;
}
template<typename T>
inline T & DynamicArray<T>::at(int place)
{
return myArray[place];//return the element at place
}
template<typename T>
inline T & DynamicArray<T>::front()
{
return myArray[0];//return the first element in the array
}
template<typename T>
inline T & DynamicArray<T>::back()
{
return myArray[sizeofarray];//return the last element in the array
}
template<typename T>
inline T & DynamicArray<T>::operator[](int place)
{
return myArray[place];//return the element at place using subscript operator instead of dynarray.at()
}
template<typename T>
inline size_t DynamicArray<T>::capacity()
{
return back() - front();//
}
template<typename T>
inline size_t DynamicArray<T>::max_size()
{
return std::numeric_limits<T>::max();
}
template<typename T>
inline DynamicArrayIter<T> DynamicArray<T>::begin()
{
return DynamicArrayIter<T>(myArray);
}
template<typename T>
inline DynamicArrayIter<T> DynamicArray<T>::end()
{
return DynamicArrayIter<T>(myArray + sizeofarray - 1);
}
template<typename T>
inline void DynamicArray<T>::clear()
{
sizeofarray = 0;
myArray = new T[sizeofarray];
myArray[0] = NULL;
}
template<typename T>
inline int DynamicArray<T>::size()
{
return sizeofarray;
}
size() returns the number of elements that are held by the container while capacity is how many elements it can hold before more space must be allocated. So capacity can be greater than the size of the vector.
In your implementation, you have to create one more member capacity that will store the actual size of allocated array whereas size will hold the number of elements the container is holding.

Adding to dynamic array

Disclaimer: Yes, I know about std::vector. I'm doing this for the sake of learning.
I'm working on making a dynamic array class, and I'm trying to get add to work.
template <class T>
void Array<T>::add(T value)
{
T * tmp = new T[mCount];
for (int i = 0; i < mCount; i++)
{
tmp[i] = mData[i];
}
mCount++;
delete[] mData;
mData = tmp;
mData[mCount - 1] = value;
}
It works... sort of. The function works in adding the element, but then the program crashes when exiting. No errors, no nothing. It just freezes, and I have to close it using (Shift + F5).
So, what's wrong with this?
Here's my whole class. If I didn't include a function it means there's no code in it.
#ifndef ARRAY_H
#define ARRAY_H
using namespace std;
template <class T>
class Array
{
private:
T * mData;
int mCount;
public:
Array();
~Array();
void add(T value);
void insert(T value, int index);
bool isEmpty();
void display();
bool remove(T value);
bool removeAt(int index);
int size();
T & operator[](const int index);
};
// Constructors / Destructors
// --------------------------------------------------------
template <class T>
Array<T>::Array()
{
mCount = 0;
mData = new T[mCount];
for (int i = 0; i < mCount; i++)
mData[i] = 0;
}
template <class T>
Array<T>::~Array()
{
delete[] mData;
}
// General Operations
// --------------------------------------------------------
template <class T>
void Array<T>::add(T value)
{
T * tmp = new T[mCount];
for (int i = 0; i < mCount; i++)
{
tmp[i] = mData[i];
}
mCount++;
delete[] mData;
mData = tmp;
mData[mCount - 1] = value;
}
template <class T>
void Array<T>::display()
{
if (isEmpty())
{
cout
<< "The array is empty."
<< "\n\n";
return;
}
cout << "(";
for (int i = 0; i < mCount; i++)
{
cout << mData[i];
if (i < mCount - 1)
cout << ", ";
}
cout << ")" << "\n\n";
}
template <class T>
bool Array<T>::isEmpty()
{
return mCount == 0;
}
template <class T>
int Array<T>::size()
{
return mCount;
}
// Operator Overloads
// --------------------------------------------------------
template <class T>
T & Array<T>::operator[](const int index)
{
return mData[index];
}
#endif
If you need any additional info lemme know and I can post it.
Assuming mCount keeps the number of elements in the array, then when adding a new element you really have to allocate at least mCount + 1 elements (assuming of course you want to keep all the old ones and the new one) via:
T * tmp = new T[mCount + 1];
as opposed to:
T * tmp = new T[mCount];
If it's for anything else other than educational purposes, please use std::vector instead. For example your add function is not exception safe.

Array resize function in dynamic memory

I'm making a function to resize an array in dynamic memory and it's not working..
here's the code:
template <class Type>
void Array<Type>::Resize(int newSize)
{
if(newSize==size)
return;
if(newSize<=0)
return;
Type *temp = new Type[newSize];
int min=(newSize>size)?size:newSize;
for(int i=0; i<min; i++)
temp[i]=elements[i];
delete []elements;
elements = temp;
temp = NULL;
}
the problem is in these two statements
delete []elements;
elements = temp;
cause when i comment them the program works properly,
but it actually doesn't do what is supposed to do..
I think the problem is something that is being destroyed when getting out of the function scope and I have to call it by reference but I can't actually cause this is a member function.
Here's the whole header file:
#include<string>
#include<iostream>
using namespace std;
#ifndef ARRAY_H
#define ARRAY_H
template <class Type>
class Array
{
public:
Array (int s);
Array (const Array& obj);
~Array ();
const Array& operator= (const Array& obj);
Type GetElement (int index) const;
void SetElement (Type ele, int index);
void Resize (int newSize);
void Print () const;
void Destroy ();
private:
int size;
Type* elements;
};
template <class Type>
Array<Type>::Array(int s)
{
if(s<0)
return;
size=s;
elements = new Type[size];
}
template <class Type>
Array<Type>::Array(const Array &obj)
{
size = obj.size;
elements = new Type[size];
for(int i=0; i<size; ++i)
elements[i]=obj.elements[i];
}
template <class Type>
Array<Type>::~Array()
{
delete [] elements;
elements = NULL;
size = 0;
}
template <class Type>
void Array<Type>::Destroy()
{
delete [] elements;
elements = NULL;
size = 0;
}
template <class Type>
const Array<Type> &Array<Type>::operator=(const Array &obj)
{
if(this != &obj)
{
size = obj.size;
if(elements != NULL)
delete [] elements;
elements = new Type[size];
for(int i=0; i<size; i++)
elements[i] = obj.elements[i];
}
return *this;
}
template <class Type>
Type Array<Type>::GetElement(int index) const
{
if(index<0 || index>=size)
cout << "Sorry, this operation can not be proceeded \n";
else
return elements[index];
}
template <class Type>
void Array<Type>::SetElement(Type ele, int index)
{
if(index<0 || index>=size){
cout << "Sorry, this operation can not be proceeded \n";
return; }
else
elements[index] = ele;
}
template <class Type>
void Array<Type>::Print() const
{
for(int i=0;i<size; ++i)
cout << elements[i] << endl;
}
template <class Type>
void Array<Type>::Resize(int newSize)
{
if(newSize==size)
return;
if(newSize<=0)
return;
Type *temp = new Type[newSize];
int min=(newSize>size)?size:newSize;
for(int i=0; i<min; i++)
temp[i]=elements[i];
delete []elements;
elements = temp;
temp = NULL;
}
#endif
You forgot to do one thing in the Resize() function, and that is to update the member size with the new size after reallocation. This will cause it to access memory beyond the end of the buffer after a resize with a smaller new dimension, e.g.:
Array<int> arr(10);
// set the 10 values
arr.Resize(5);
// here the buffer will have 5 elements, but arr.size is still 10
arr.Print(); // this will read elements 0 - 9, not 0 - 4
Couple of observations
if(newSize==size)
size does not exist
delete []elements;
elements = temp;
You are attempting to copy to an array you have just deleted, which was never created in the first place.
What is meant by "does not work" and "the program works properly,"?