Problem freeing memory (subject Template) - c++

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;
}

Related

HEAP CORRUPTION DETECTED : after normal block ()

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;
}

Cannot resize stack of type template

Im trying to resize my stack but my program keeps terminating after the 'cout'.
On the output terminal it displays 1 and then the program terminates. In this case T is an int and size is set to 10 by default. Any help will be much appreciated.
#include <iostream>
#include <fstream>
using namespace std;
template <typename T>
class stack {
public:
int topStack;
T* stack1;
int size;
void copy(const stack& other);
void move(stack&& other);
// constructor
stack ();
// destructor
~stack()
{
delete[] stack1;
};
// copy constructor
stack (const stack&);
// copy assignment
stack& operator= (const stack&);
// move constructor
stack (stack&&);
// move assignment
stack& operator= (stack&&);
T& top() const; // return the top element
void pop (); // remove the top element
void push(const T&); // add element on top of stack
void push (T&&); // add element on top of stack
bool empty() const; // is the stack empty?
void clear(); // remove all elements
ostream& print(ostream&, stack&);
void resize();
};
//Default Constructor
template <typename T>
stack<T>::stack()
{
size=10;
stack1= new T[size];
for(int b =0; b < size; b ++)
{
stack1[b] = T();
}
topStack =-1;
}
//Copy Constructor
template <typename T>
void stack<T>::copy(const stack& other)
{
topStack = other.topStack;
stack1= new T[other.size];
size =other.size;
for(int i=0; i< other.size ; i++)
{
stack1[i]=other.stack1[i];
}
}
//Copy assignment
template <typename T>
stack<T>& stack<T>::operator =(const stack& other)
{
if (this == &other) return *this;
T* store = new T[other.size];
for(int g =0; g < other.size ; g++)
{
store[g]= other.stack1[g];
}
delete[] stack1;
this->stack1 = store;
this->size = other.size;
this-> topStack = other.topStack;
return *this;
}
//Move Constructor
template<typename T>
void stack<T>::move(stack && other)
{
topStack = other.topStack;
other.topStack = 0;
stack1 = other.stack1;
for(int u =0; u < other.size ; u++)
{
other.stack1[u]=0;
}
size = other.size;
other.size=0;
}
//Move assignment
template <typename T>
stack<T>& stack<T>::operator= (stack&& other)
{
this->size = other.size;
other.size=0;
this->topStack = other.topStack;
other.topStack=0;
this->stack1 = other.stack1;
for(int u =0; u < this->size ; u++)
{
other.stack1[u]=0;
}
return *this;
}
//Checks if stack is empty
template <typename T>
bool stack<T>::empty() const
{
return topStack == -1;
}
//Resize array
template<typename T>
void stack<T>::resize()
{
cout << "DAYYYY55UM";
T* storage = new T[this->size*2];
cout << "DAYYYYUM";
for(int r=0; r < this->size ; r++)
{
storage[r]= this->stack1[r];
}
delete[] this->stack1;
this->stack1= storage;
this->size = size*2;
cout << "DAYYYYUM";
}
//Returns top
template <typename T>
T& stack<T>::top() const
{
if(empty())
{
cout << "ERROR: Stack is empty. "<< endl;
return;
//Make a throw catch statement here
}
return stack1[topStack];
}
//Pop
template <typename T>
void stack<T>::pop()
{
if(empty())
{
cout << "ERROR: Stack is empty." << endl;
return;
}
stack1[topStack] =0;
topStack--;
}
//Push
template <typename T>
void stack<T>::push(const T& q)
{
if(topStack < size)
{
topStack++;
stack1[topStack] = q;
}else{
resize();
}
}
//Push
template <typename T>
void stack<T>::push(T&& q)
{
if(topStack < size)
{
topStack++;
stack1[topStack] = q;
}else{
resize();
}
}
//Print Function
template <typename T>
ostream& stack<T>::print(ostream& os, stack& other)
{
os << other.stack1 ;
}
template <typename T>
void stack<T>::clear()
{
for(int g=0; g < size; g++ )
{
stack1[g]=0;
}
}
int main()
{
stack<int> world;
world.push(9);
world.push(40);
world.push(40);
world.push(9);
world.push(40);
world.push(40);
world.push(9);
world.push(40);
world.push(40);
world.push(9);
world.push(40);
world.push(40);
cout << world.stack1[12] << endl;
return 0;
}
That error means that you have an out of bounds array access somewhere that is corrupting malloc's data structures.
The error is in your push function:
template <typename T>
void stack<T>::push(T&& q)
{
if(topStack < size)
{
topStack++;
stack1[topStack] = q;
}else{
resize();
}
}
When you write the last item before resize, topStack is one less than size, which is a valid index (the last one, indeed), but then you increment it to size, and write the item in that position, and that's not a valid index.
By the way, you have a lot of errors with the indexes al over your class. My advice woulbe to take into account that c++ arrays start at 0 and end at size-1, and revise your code.
And have you noticed that when you resize the array you don't add the new item?

Error with the Copy constructor and equality operator

I am making my own implementation of the class "vector" with templates as practise. Everything seems to be working except the Copy constructor and the overloaded = operator. I am not sure where exactly the problem is. I will post the entire source code below:(Also I am not sure if I have any leaks)
#include <iostream>
#include <string>
using namespace std;
template <typename TT1>
class Vector{
private:
int size;
TT1* ptr;
public:
Vector();
~Vector();
Vector(int size);
Vector(const Vector& a);
Vector<TT1>& operator=(const Vector& a);
void set(int position, TT1 data);
TT1 get(int position);
int get_size();
};
//------Default Constructor------
template <typename TT1>
Vector<TT1> :: Vector()
{
size = 0;
ptr = NULL;
}
//-------Copy Constructor-------
template <typename TT1>
Vector<TT1> :: Vector(const Vector<TT1>& a)
{
if(a.ptr != NULL)
{
this->size = a.size;
delete[] ptr;
ptr = new TT1[size];
for ( int i = 0; i < this->size; i++)
this->ptr[i] = a.ptr[i];
}
}
//------Destructor-------
template <typename TT1>
Vector<TT1> :: ~Vector()
{
delete[] ptr;
}
//-----Overloaded = operator----
template <typename TT1>
Vector<TT1>& Vector<TT1> :: operator=(const Vector<TT1>& a)
{
if(this != &a)
{
this->size = a.size;
delete[] this->ptr;
this->ptr = new TT1[a.size];
for (unsigned int i = 0; i < this->size; i++)
this->ptr[i] = a.ptr[i];
return *this;
}
}
//----Constructor with size---
template<typename TT1>
Vector<TT1> :: Vector(int size)
{
this->size = size;
ptr = new TT1[size];
}
//---- Set data # Poisition----
template<typename TT1>
void Vector<TT1> :: set(int position, TT1 data)
{
*(ptr+ position) = data;
}
//----Get data From position----
template<typename TT1>
TT1 Vector<TT1> :: get(int position)
{
return *(ptr + position);
}
//-----Get size----
template<typename TT1>
int Vector<TT1> :: get_size()
{
return size;
}
void foo(Vector<string> a)
{
}
int main()
{
Vector<string> a(3);
a.set(0, "asd");
a.set(2, "hjk");
a.set(1, "34645!");
for(int i = 0; i < a.get_size(); i++)
{
cout << a.get(i) << endl;
}
Vector<string> b = a;
for(int i = 0; i < a.get_size(); i++)
{
cout << b.get(i) << endl;
}
foo(a);
return 0;
}
And now the parts where the mistakes are:
template <typename TT1>
Vector<TT1> :: Vector(const Vector<TT1>& a)
{
if(a.ptr != NULL)
{
this->size = a.size;
delete[] ptr;
ptr = new TT1[size];
for ( int i = 0; i < this->size; i++)
this->ptr[i] = a.ptr[i];
}
}
And finally here:
//-----Overloaded = operator----
template <typename TT1>
Vector<TT1>& Vector<TT1> :: operator=(const Vector<TT1>& a)
{
if(this != &a)
{
this->size = a.size;
delete[] this->ptr;
this->ptr = new TT1[a.size];
for (unsigned int i = 0; i < this->size; i++)
this->ptr[i] = a.ptr[i];
return *this;
}
You delete a pointer that was never allocated:
//-------Copy Constructor-------
template <typename TT1>
Vector<TT1> :: Vector(const Vector<TT1>& a)
{
std::cout << "Vector(const Vector<TT1>& a), " << a.size << std::endl;
if(a.ptr != NULL)
{
this->size = a.size;
delete[] ptr; //<-------------- no corresponding new
ptr = new TT1[size];
for ( int i = 0; i < this->size; i++)
this->ptr[i] = a.ptr[i];
}
}
Just comment that out, and it works fine.
Edit: Per Mike Seymour's observation, the members esp. ptr should be initialized:
Vector<TT1> :: Vector(const Vector<TT1>& a) : size(0), ptr(NULL)
{
...
}
In addition, although the compiler accepts it for constructor/operator= apparently, you will otherwise get an 'incomplete type' error if you write code of the form
Vector(const Vector& a);
Vector<TT1>& operator=(const Vector& a);
Rather, for consistency and good style imho include the template parameters:
Vector(const Vector<TT1>& a);
Vector<TT1>& operator=(const Vector<TT1>& a);
And similarly in the definitions.

c++ using vector of employee pointers

I have created my vector class template and I have already done my employee classes of hourly and I salaried. I want to use the vector of employee pointers instead of the array of employee pointers, I'm trying to do that but when I run it just breaks while I have no error listed.
Also, I have used the at function like( payroll.at(i)->writeFile(out); ) to get access to an element, but I don't know what's wrong.
Any suggestion?
Thanks
here is my code:
myvector class template:
#include <iostream>
#include <string>
#include <cassert>
#include <algorithm>
const int CAPACITY = 4;
template <class T>
class MyVector {
public:
MyVector();
MyVector( int size);
MyVector( int size, const T & initial);
MyVector(const MyVector<T> & v);
~MyVector();
int capacity() const;
int size() const;
void push_back(const T & value);
//T & operator[](unsigned int index);
MyVector<T> & operator=(const MyVector<T> &);
void clear();
T at(int i);
friend ostream& operator<<(ostream &out, const MyVector<T>& );
private:
int applied;
int my_size;
int my_capacity;
T * buffer;
T * daArray;
};
template<class T>
MyVector<T>::MyVector()
{
my_capacity = 0;
my_size = 0;
buffer = 0;
applied = 0;
}
template<class T>
MyVector<T>::MyVector(const MyVector<T> & v)
{
my_size = v.my_size;
my_capacity = v.my_capacity;
buffer = new T[my_size];
for ( int i = 0; i < my_size; i++)
buffer[i] = v.buffer[i];
}
template<class T>
MyVector<T>::MyVector(int size)
{
my_capacity = size;
my_size = size;
buffer = new T[size];
}
template<class T>
MyVector<T>::MyVector( int size, const T & initial)
{
my_size = size;
my_capacity = size;
buffer = new T [size];
for (unsigned int i = 0; i < size; i++)
buffer[i] = initial;
//T();
}
template<class T>
MyVector<T> & MyVector<T>::operator = (const MyVector<T> & v)
{
delete[ ] buffer;
my_size = v.my_size;
my_capacity = v.my_capacity;
buffer = new T [my_size];
for (int i = 0; i < my_size; i++)
buffer[i] = v.buffer[i];
return *this;
}
template<class T>
void MyVector<T>::push_back(const T & i)
{
if (my_capacity == 0)
{
my_capacity = 1;
my_size = 1;
applied= 0;
buffer = new T[1];
buffer[0] = i;
}
else
{
if (applied+1 == my_capacity)
{
int newCapacity = my_capacity * CAPACITY;
daArray = new T[newCapacity];
for (int i = 0; i < my_size; i++)
{
daArray[i] = buffer[i];
}
my_capacity = newCapacity;
delete buffer;
my_size++;
applied++;
buffer[applied] = i;
}
else
{
if (my_size == applied + 1)
my_size++;
applied++;
buffer[applied] = i;
}
}
}
template<class T>
int MyVector<T>::size()const//
{
return my_size;
}
template<class T>
int MyVector<T>::capacity()const
{
return my_capacity;
}
template<class T>
MyVector<T>::~MyVector()
{
delete[ ] buffer;
}
template <class T>
void MyVector<T>::clear()
{
my_capacity = 0;
my_size = 0;
buffer = 0;
}
template <class T>
T MyVector<T>::at(int i)
{
if (i < 0 || i > my_size -1)
{
string error = "Index is undefined";
throw error;
}
return buffer[i];
}
template <class T>
ostream& operator<<(ostream &out, const MyVector<T>& v)
{
for (unsigned i = 0; i < v.size(); i++)
{
out << v[i] << " ";
}
return out;
}
main
int main() {
MyVector< employee*> payroll;
payroll.push_back(new Hourly ("H. Potter", "Privet Drive", "201-9090", 40, 12.00));
payroll.push_back(new Salaried ( "A. Dumbledore", "Hogewarts", "803-1230", 1200));
ofstream out;
out.open(file);
if (out.fail()) {
cout<<" could not open the file"<<endl;
system("PAUSE");
}
for (int i = 0; i < SIZE; i++) {
payroll.at(i)->writeFile(out);
}
out.close( );
}
You have a bug in your push_back method. You need something like this
if (applied+1 == my_capacity)
{
int newCapacity = my_capacity * CAPACITY;
daArray = new T[newCapacity];
for (int i = 0; i < my_size; i++)
{
daArray[i] = buffer[i];
}
my_capacity = newCapacity;
delete buffer;
buffer = daArray; // new line here
my_size++;
applied++;
buffer[applied] = i;
}
See where I've put the comment // new line here

C++ How to use std::sort to sort a array of objects in c++

I have the template class and array of pointers to objects and overloaded logic operators for my objects. My bubble sort is working. So it's know how to compare my objects
I want to replace it with standard sort
Declaration
Implementation List.tem
#include <stdio.h>
#include <stdlib.h>
#include <vector>
///////////////
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
template <class Type>
List<Type>::List()
{
itemPtr = NULL;
used = 0;
size = 0;
}
template <class Type>
List<Type>::List(const List<Type>& source)
{
itemPtr = NULL;
used = 0;
size = source.size;
itemPtr = new Type[size];
for(int i = 0; i < source.used; i++)
addItem(source.itemPtr[i]);
}
template <class Type>
List<Type>& List<Type>::operator = (const List<Type>& source)
{
used = 0;
if(this == &source)
return(*this);
free();
size = source.size;
itemPtr = new Type[size];
for(int i = 0; i < source.used; i++)
addItem(source.itemPtr[i]);
return(*this);
}
template <class Type>
List<Type>::~List()
{
free();
}
template <class Type>
void List<Type>::free()
{
if(itemPtr != NULL)
{
delete [] itemPtr;
itemPtr = NULL;
}
}
template <class Type>
void List<Type>::alloc(int sizeIcrease)
{
Type* tmpPtr = NULL;
size += sizeIcrease;
tmpPtr = new Type[size];
copy(itemPtr, itemPtr+used, tmpPtr);
free();
itemPtr = tmpPtr;
}
template <class Type>
Type List<Type>::getItem(int index) const
{
Type item;
if(index >= 0 && index < used)
item = itemPtr[index];
return (item);
}
template <class Type>
int List<Type>::findItem(Type itemIn)
{
int i = 0;
for(i = 0; i < used; i++)
if(itemPtr[i] == itemIn)
break;
if (i == used) i = -1;
return (i);
}
template <class Type>
void List<Type>::addItem(Type itemIn)
{
if(used == size) alloc(10);
itemPtr[used++] = itemIn;
bubbles();
}
template <class Type>
void List<Type>::removeItem(Type itemIn)
{
int index = findItem(itemIn);
removeItem(index);
}
template <class Type>
void List<Type>::removeItem(int index)
{
if(index >= 0 && index < used)
itemPtr[index] = itemPtr[--used];
bubbles();
}
template <class Type>
void List<Type>::readFile(Field fileName)
{
Type itemTmp;
ifstream inFile(fileName.c_str());
if(!inFile)
cout << "Error opening file\n";
do
{
inFile >> itemTmp;
if(!inFile.fail())
addItem(itemTmp);
} while (!inFile.fail());
//bubbles();
vector<Type*> myvector; //(itemPtr, itemPtr+used);
vector<Type>::iterator it;
sort (myvector.begin(), myvector.end(), sort_by_pointee<Type>());
inFile.close();
}
template <class Type>
void List<Type>::writeFile(Field fileName)
{
ofstream outFile;
outFile.open(fileName.c_str());
if(!outFile)
cout << "Error opening file\n";
for(int i = 0; i < used; i++)
{
outFile << itemPtr[i] << "\n";
}
outFile.close();
}
template <class Type>
void List<Type>::print()
{
//////Coded
}
template <class Type>
void List<Type>::bubbles()
{
////// Coded
}
template <class Type>
ostream& operator<<(ostream& os, const List<Type>& ad)
{
for(int i = 0; i < ab.used; i++)
os << ab.getItem(i) << endl;
return os;
}
template <class Type>
ofstream& operator<<(ofstream& ofs, const List<Type>& ad)
{
for(int i = 0; i < ab.used; i++)
ofs << ab.getItem(i) << ",";
return ofs;
}
template<class Type>
struct sort_by_pointee
{
bool operator() (const Type* lhs, const Type* rhs) const
{
return (*lhs < *rhs);
}
};
If the third argument to std::sort() is not provided, objects are sorted using operator< like:
if (a < b) {
// ...
}
So all you need to sort objects of type Foo is to have either:
bool Foo::operator< (const Foo& rhs) const;
or
bool operator< (const Foo& lhs, const Foo& rhs);
That being said, if you have an array of pointers, then you will need to provide a custom predicate unless you want to sort objects by their memory address (I highly doubt this is what you want). You can do something like:
template<class T>
struct sort_by_pointee {
bool operator() (const T* lhs, const T* rhs) const
{
return (*lhs < *rhs);
}
};
And use it like:
std::vector<Foo*> foos;
// ...
std::sort(foos.begin(), foos.end(), sort_by_pointee<Foo>());
Edit: the sample you posted will work fine and sort the data, but the vector does not act as a proxy for the data stored in the itemPtr array. Read it again with my annotations:
{
vector<Type> myvector (itemPtr, itemPtr+8);
// 'myvector' holds a copy of the first 8 elements in the 'itemPtr' array.
sort (myvector.begin(), myvector.end());
// contents of 'myvector' are sorted, but this is a copy of 'itemPtr''s
// contents, so items in 'itemPtr' are still in their original order.
}
If you want to sort the contents of [itemPtr,itemPtr+8) in-place, you can just do:
std::sort(itemPtr, itemPtr+8); // use custom predicate if required.
Edit: OK, following the code you posted, I would fix the readFile() method from its original definition to:
template <class Type>
void List<Type>::readFile(Field path)
{
ifstream file(path.c_str());
if(!file.is_open()) {
cout << "Error opening file\n";
}
for (Type item; file >> item;) {
addItem(item);
}
sort (itemPtr, itemPtr+used);
}