I am building a class to manage memory for a program and I am testing it out to make sure it does what I need it to do for my program. Everything works but printing out my mem_end() iterator.
I get this error message: can't dereference out of range vector iterator
Why is this happening? I have confirmed that all elements are in the vector from my temp vector in my testing unit.
Here is my code:
#include <iostream> // input output services
#include <string> // provides acess to string types
#include <cstdlib> // provides access to random number generation and dynamic
// memory management
#include <ctime> // provides the ability to manipulate date and time management
#include <vector> // Part of STL & provides access to vectors that are similar to
// dynamic arrays that have the ability to resize themselves
#include <memory> // more functionality to manage dynamic memory
#include <cmath> // access to math funtctions as computations
#include <iomanip> // Access to set precision
using namespace std;
using std::cout;
// Memory class to manage memory for the program which as a template accepts
// any data type. Manual memory deletion is required
template <class K> // I know its usually T
class Memory
{
//"Protected" keyword used to limit access outside of Memory but can be accessed by
// derived classes.
protected:
// Main array for my Memory class
vector<K> mem_array;
public:
Memory() {}; // Default empty constructor for Memory class
Memory(const Memory&); // Copy constructor
Memory<K>& operator = (const Memory&); // Assignment operator
unsigned mem_size();
void push_back(K);
void del_mem(int);
void clear_mem();
K& operator[](int);
typedef typename std::vector<K>::iterator iterator; // Iterator functionality
// for Memory class
iterator mem_begin() { return this->mem_array.begin(); }; // returns the first element
// of mem_array
iterator mem_end() { return this->mem_array.end(); }; // returns the last element of
// mem_array
void show_mem();
void memory_test_unit();
};
int main()
{
Memory<int> mTest;
mTest.memory_test_unit(); // For testing code along the way
}
// Method for testing the functionality of my Memory class
template <class K>
void Memory<K>::memory_test_unit()
{
vector<int> temp = { 5,4,3 };
setprecision(1);
Memory<int> mI; //access to Memory with int as the specified data type
Memory<double> mD; // same thing with double
mI.del_mem(1); // Error no elements in mem_array
cout << mI.mem_size() << endl; // size is zero
cout << mD.mem_size() << endl;
mI.push_back(2);
mD.push_back(13.4);
cout << mI.mem_size() << endl; // size is one
cout << mD.mem_size() << endl;
//Int array
mI.show_mem();
// Double array
mD.show_mem();
mI.del_mem(4); // Error mem_array does not have 4 elements
mI.del_mem(0);
cout << mI.mem_size() << endl; // size is zero again
mI.show_mem(); // no elements to print
for (int i = 0; i < temp.size(); i++) {
mI.push_back(temp.at(i));
}
mI.show_mem(); // Print mem_array
mI.clear_mem();
mI.show_mem(); // No elements to print again
cout << mI.mem_size() << endl; // size is zero again
for (int i = 0; i < temp.size(); i++) {
mI.push_back(temp.at(i));
}
mI.show_mem(); // Print mem_array
mI.clear_mem();
mI.show_mem(); // Print no elements to show
for (int i = 0; i < temp.size(); i++) {
mI.push_back(temp.at(i));
}
mI.show_mem(); // Prints new loaded vector
cout << endl;
cout << *mI.mem_begin(); // should print 5, * to acess iterator
cout << *mI.mem_end(); // should print 3 - error message here
}
// Memory class things ~
// Copy constructor for my Memory class (allows for deep copy from dissimilar references)
template <class K>
Memory<K>::Memory(const Memory& m)
{
this->mem_array = m.mem_array;
}
//Overloaded assignment operator that works with deep copying
template<class K>
Memory<K>& Memory<K>::operator = (const Memory& m)
{
// Prevents from copying its own memory
if (this != &m) {
this->mem_array = m.mem_array;
}
return *this;
}
// Method for returning the size of mem_array
template <class K>
unsigned Memory<K>::mem_size()
{
return this->mem_array.size();
}
// Method to allow acess to mem_array to add data
template <class K>
void Memory<K>::push_back(K dat)
{
this->mem_array.push_back(dat);
}
// Method to print the contents of mem_array for testing
template <class K>
void Memory<K>::show_mem()
{
int msize = mem_size();
for (int i = 0; i < msize; i++) {
cout << this->mem_array.at(i) << "\n";
}
if (msize > 0) {
cout << this->mem_array[0];
}
else {
cout << "\nNo elements to show! \n";
}
}
// Method to delete a single element from mem_array in a range
template <class K>
void Memory<K>::del_mem(int indx)
{
if (this->mem_array.size() > 0)
{
if (indx >= 0 && indx <= static_cast<int>(this->mem_array.size()) - 1)
{
this->mem_array.erase(this->mem_array.begin() + indx);
}
else
{
std::cout << "\nError(erase): index (" << indx << ") out of bounds of array!\n" << std::endl;
//exit(0);
}
}
else
{
std::cout << "\nError(erase): you can't delete items from an empty array!\n" << std::endl;
//exit(0);
}
}
// Method to clear all elements from mem_array
template <class K>
void Memory<K>::clear_mem()
{
this->mem_array.clear();
}
// Method to overload the subscript operator
template <class K>
K& Memory<K>::operator[](int indx)
{
if (indx >= 0 && indx <= static_cast<int>(this->mem_array.size()) - 1)
return this->mem_array[indx];
else
{
std::cout << "Error(access): index (" << indx << ") out of bounds of array!" << std::endl;
//exit(0);
}
}
I used my show_mem() function to verify that all from temp are loaded into mem_array.