Doesn't work Copy Assignment Operator - c++

In my code, I am having trouble on my copy assignment operator. When I try to execute "=" operator in my main(), the content of my source array (numArr) is not copied to my destenation array (numArr2).
Then, for my doubleCap() function, I am try to create a bigger array of double size once my original array is full. However, if I insert delete[] newArr, the compiler will output some random numbers in my array.
This is my code in .cpp
#include <iostream>
#include "NumList.h"
using namespace std;
//Default Constructor
NumList::NumList()
{
//Actual elements stored in the array
size = 0;
//Max capacity of the array
capacity = 1;
numList = new int[capacity];
}
//Destructor
NumList::~NumList()
{
delete[] numList;
}
//Copy Constructor
NumList::NumList(const NumList& anotherNumList)
{
capacity = anotherNumList.capacity;
size = anotherNumList.size;
numList = new int[capacity];
for (int i = 0; i < size; ++i)
{
numList[i] = anotherNumList.numList[i];
}
}
//Copy Assignment Operator
NumList& NumList::operator= (const NumList& anotherNumList)
{
//Check if it is self-assigning
if (this == &anotherNumList)
return *this;
//Get rid of the old data
delete[] numList;
this->capacity = anotherNumList.capacity;
//Create and copy to the new array
numList = new int[capacity];
for (int i = 0; i < anotherNumList.size; ++i)
{
numList[i] = anotherNumList.numList[i];
}
return *this;
}
void NumList::print()
{
for (int i = 0; i < size; ++i)
{
cout << numList[i] << " ";
}
cout << endl;
}
void NumList::doubleCap()
{
capacity = capacity * 2;
//Create a new array when the capacity is full
int * newArr = new int[capacity];
for (int i = 0; i < size; ++i)
{
newArr[i] = numList[i];
}
//Let numlist points to the new array
numList = newArr;
//delete[] newArr; <--
}
void NumList::insertEnd(int val)
{
//Double the capacity of the list
if (size == capacity)
{
doubleCap();
}
numList[size] = val;
++size;
}
void NumList::insertAt(int val, int index)
{
if (index < 0 || index > capacity)
{
cout << "The index is out of range." << endl;
}
else
{
//Double the capacity of the list
if (size == capacity)
{
doubleCap();
}
for (int i = (size-1); i >= index; i--)
{
numList[i + 1] = numList[i];
}
numList[index] = val;
++size;
}
}
This is my code in main
#include <iostream>
#include <string>
#include <algorithm>
#include "NumList.h"
using namespace std;
int main()
{
NumList numArr;
NumList numArr2;
numArr.insertEnd(10);
cout << "List 1 after inserting 10: ";
numArr.print();
numArr2 = numArr;
NumList numArr3(numArr);
numArr.insertEnd(11);
numArr.insertEnd(12);
numArr.insertAt(5, 0);
cout << "List 1: ";
numArr.print();
cout << "\nPrint the list 2 of int: ";
numArr2.print();
cout << "\nPrint the list 3 of int: ";
numArr3.print();
system("pause");
return 0;
}
Output without line "delete[] newArr;",
List 1 after inserting 10: 10
List 1: 5 10 11 12
Print the list 2 of int:
Print the list 2 of int: 10
Press any key to continue . . .
Output with line "delete[] newArr;",
List 1 after inserting 10: 10
List 1: 5 -572662307 -572662307 12
Print the list 2 of int:
Print the list 2 of int: 10
Press any key to continue . . .

You are trying to delete the wrong thing. In doubleCap() you have 2 arrays, the member and the new on you create that has more space. The one that has more space is the one you want to keep so you can't delete it. What you need to do is delete the original array and then assign to it the new one. That makes the function look like
void NumList::doubleCap()
{
capacity = capacity * 2;
//Create a new array when the capacity is full
int * newArr = new int[capacity];
for (int i = 0; i < size; ++i)
{
newArr[i] = numList[i];
}
delete [] numList; // get rid of the old array
//Let numlist points to the new array
numList = newArr;
}
You are also missing the assignment of anotherNumList.size to this->size in your operator =. That causes the copied list to have the wrong size after assignment.

Related

How can i create push_back function of dynamic array?

Im trying to create this and add push back functionality. How can i do it? I came up with this code but im very confused for 2 days because it gives this output - | -842150451 | -842150451 | -842150451 | -842150451 | -842150451 | -842150451 | -842150451 | -842150451
I will be thankful if someone can tell me how this function push_back should look or at least point me in the right direction. Also i would be thankful if you tell me where this code is doing wrong?
struct IntArray{
private:
int k;
int* first_cell;
int size; // currently occupied elements
int capacity = 8; // size of the allocated memory
public:
void create() {
first_cell = (int*)malloc(capacity * sizeof(int));
}
void random_numbers_fill(int limit) {
srand(time(NULL));
for (k = 0; k < capacity; k++) {
first_cell[k] = rand() % limit;
}
}
void push_back(int number) {
if (size == capacity) {
int* new_arr;
capacity *= 2;
new_arr = (int*)malloc(capacity * sizeof(int));
for (k = 0; k < capacity; k++) {
new_arr[k] = first_cell[k];
}
free(first_cell);
first_cell = new_arr;
first_cell[size] = number;
size++;
}
}
void print() {
for (k = 0; k < capacity; k++) {
printf("| %d ", first_cell[k]);
}
First, create() should be changed into an actual constructor. And you are missing a destructor to free the array, as well as copy/move constructors and copy/move assignment operators to manage the array (per the Rule of 3/5/0).
Second, you should be using new[] instead of malloc().
Third, regarding your push_back(), it is not a bad attempt, but it is buggy. You are not adding the number to the array at all if the current size is less than the current capacity (and your constructor is not initializing size at all). And when you do resize + copy the array, you are copying too many ints from the old array. The old array is size elements, but you are trying to copy the newly increased capacity elements from it.
With that said, try something more like this instead:
#include <iostream>
#include <algorithm>
#include <utility>
class IntArray{
private:
int* first_cell = nullptr;
int size = 0; // currently occupied elements
int capacity = 8; // size of the allocated memory
public:
IntArray()
{
first_cell = new int[capacity];
}
IntArray(const IntArray &src)
: size(src.size), capacity(src.capacity)
{
first_cell = new int[capacity];
std::copy_n(src.first_cell, size, first_cell);
}
IntArray(IntArray &&src)
: first_cell(src.first_cell), size(src.size), capacity(src.capacity)
{
src.first_cell = nullptr;
src.size = src.capacity = 0;
}
~IntArray()
{
delete[] first_cell;
}
IntArray& operator=(IntArray rhs)
{
IntArray temp(std::move(rhs));
std::swap(first_cell, temp.first_cell);
std::swap(size, temp.size);
std::swap(capacity, temp.capacity);
return *this;
}
void push_back(int number)
{
if (size == capacity)
{
int new_cap = capacity * 2;
int* new_arr = new int[new_cap];
for (int k = 0; k < size; ++k) {
new_arr[k] = first_cell[k];
}
delete[] first_cell;
first_cell = new_arr;
capacity = new_cap;
}
first_cell[size] = number;
++size;
}
void print() const
{
for (int k = 0; k < size; ++k) {
std::cout << "| " << first_cell[k] << " ";
}
}
};
That being said, you should just get rid of your manual array and use std::vector<int> instead, as it handles all of these details for you, eg:
#include <iostream>
#include <vector>
class IntArray{
private:
std::vector<int> vec;
public:
IntArray()
{
vec.reserve(8);
}
void push_back(int number)
{
vec.push_back(number);
}
void print() const
{
for (int number : vec) {
std::cout << "| " << number << " ";
}
}
};
You never initialize size in create.
Your push_back has two problems. You don't copy the number that is pushed unless you grow the array (the last two statements should be outside the if block), and the condition in the for loop should compare with size, not capacity.
print also has the wrong condition in the for loop.

Best practices for creating a two dimensional array of std::strings

I am new to c++ and learning how to declare, use and delete a two dimensional array of std::string.
Because this is a learning exercise I am ignoring the idea of using vectors (for now).
I wrote a program that creates a small two dimensional array, adds data and then deletes the 2d array trying to use best practices along the way.
Can someone suggest improvements? I am most concerned about cleaning up the 2d array after I'm done using it, so I can avoid the possibility of a memory leak.
Thanks in advance.
#include <iostream>
#include <string>
using namespace std;
void DIM(std::string **marray,unsigned int row,unsigned long cols)
{
if (marray[row] != nullptr) {
delete [] marray[row];
marray[row] = nullptr;
}
marray[row] = new std::string[cols];
}
void DIM_DELETE (std::string **marray,unsigned int row)
{
if (*&marray[row] != nullptr) {
delete[] marray[row];
marray[row] = nullptr;
}
}
void DIM_DELETE_ALL (std::string **marray,unsigned int rows)
{
for (int i=(rows-1); i>-1; i--) {
if (marray[i] != nullptr) {
delete[] marray[i];
marray[i] = nullptr;
}
}//next i
//now take care of marray
if (marray != nullptr) {
delete [] marray;
marray = nullptr;
}
}
std::string **create2darray(unsigned int rows,unsigned int cols)
{
//first create the pointer
std::string **my = nullptr; //create pointer , note: no data portion assigned yet
//now assign a data portion to the pointer (could do above in one step)
my = new std::string*[rows];// elements 0 through rows-1 //assigns data section (an array of std::strings)
//now set newly created rows to nullptr
for (unsigned int i = 0; i<rows; i++) {
my[i] = nullptr;
}
//dim each row for cols columns
for (unsigned int i = 0; i<rows; i++) {
DIM(my,i,cols);//dims the strings (creates data portion) my = new std::string*[x];//
}
return my;//returning a std::string **
}
int main()
{
unsigned int rows = 3;//3 rows (0 through 2)
unsigned int cols = 4;//4 columns (0 through 3)
std::string **myarray = create2darray(rows,cols);//2d array (3 rows, 5 cols)
cout << "2d array created" << endl << endl;
myarray[0][0] = "a0"; //row 0, col 0
myarray[1][0] = "b0"; //row 1, col 0
myarray[2][0] = "c0";
myarray[0][1] = "a1";
myarray[0][2] = "a2";
myarray[0][3] = "a3";
myarray[1][1] = "b1";
myarray[1][2] = "b2";
myarray[1][3] = "b3";
myarray[2][1] = "c1";
myarray[2][2] = "c2";
myarray[2][3] = "c3";
cout << "assigned data to rows 0 to 2 and cols 0 to 3" << endl << endl;
for (unsigned int i=0; i<rows; i++) {
cout << i << ",0: " << myarray[i][0] << " " << i << ",1: " << myarray[i][1] << " " << i << ",2: " << myarray[i][2] << " " << i << ",3: " << myarray[i][3] << endl;
}
cout << endl;
cout << "we are done with 2d array, let's delete it" << endl;
//tested dim_delete (seems to work)
/*
DIM_DELETE(myarray,0);//delete [] myarray[0]; myarray[0] = nullptr;
DIM_DELETE(myarray,1);
DIM_DELETE(myarray,2);
//still need to delete myarray
delete [] myarray;
myarray = nullptr;
*/
//delete all rows and delete the std::string that holds the rows
DIM_DELETE_ALL(myarray,rows);
cout << "array deleted, all done" << endl;
//hold cursor so user can see console messages
do {} while(cin.get()!='\n');
return 0;
}
If the second dimension of your array is constant, I think you can be fine using a single new and delete operators. Something like this:
#include <stdio.h>
#include <string>
int ROWS = 3;
const int COLS = 4;
typedef std::string arr4[COLS];
int main()
{
arr4 *a;
a = new arr4[ROWS];
for (int i = 0; i < ROWS; i++)
for (int j = 0; j < COLS; j++)
a[i][j] = std::to_string(j*ROWS + i);
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
printf("%s ", a[i][j].c_str());
printf("\n");
}
printf("\n");
delete [] a;
}

Code runs when in main() but gives error when in function [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am writing a dynamic matrix class that stores each non-zero value as a List of 3 elements [row,column,value]
I made a dynamic array class called "List", and class"Matrix" a List of list pointers.
My code to transpose the Matrix works:
void transpose(Matrix tripleList)
{
for (int i = 0; i < tripleList.getNumOfElem(); i++)
{
List* list = new List;
(*list).copy(*(tripleListMatrix.getAt(i)));
int temp = (*list).getAt(0);
(*list).set(0, (*list).getAt(1));
(*list).set(1, temp);
(*list).displayList();
cout << "\n";
}
}
it works when written directly in main() but gives error when in stand alone function. can anyone explains why and how to fix it?
Full code:
#include <iostream>
using namespace std;
class List //a dynamic int pointer array
{
private:
int capacity;
int numOfElem;
int *arr;
//initialize all values in capacity to 0
void initialize(int from)
{
for (int i = from; i < capacity; i++)
{
arr[i] = 0;
}
}
//double the capaicty, then initialize
void expand()
{
capacity *= 2;
int *tempArr = new int[capacity];
for (int i = 0; i < numOfElem; i++)
tempArr[i] = arr[i];
delete[] arr;
arr = tempArr;
initialize(numOfElem);
}
public:
List()//constructor
{
capacity = 10;
numOfElem = 0;
arr = new int[capacity];
}
~List()//destrcutor
{
delete[] arr;
}
//add int to the end of List
void append(int newElement)
{
if (numOfElem >= capacity)
expand();
arr[numOfElem++] = newElement;
}
//Copy all element of an input list to the end of List
void copy(List list)
{
for (int i = 0; i < list.getNumOfElem(); i++)
{
if (numOfElem >= capacity)
expand();
arr[numOfElem++] = list.getAt(i);
}
}
//get reference of the int at an index in te list
int* getAddress(int index)
{
if (index < 0 || index >= numOfElem)
throw ("Out of bounds exception!!!");
return &arr[index];
}
//change the value of at specific index
void set(int index, int value)
{
arr[index] = value;
}
//get int at an index in te list
int getAt(int index)
{
if (index < 0 || index >= numOfElem)
throw ("Out of bounds exception!!!");
return arr[index];
}
int getNumOfElem()
{
return numOfElem;
}
void displayList()
{
for (int i = 0; i < numOfElem; i++)
{
cout << arr[i] << " ";
}
}
};
class Matrix //a List of list pointers
{
private:
int capacity;
int numOfElem;
List* *arr;
void initialize(int from)
{
for (int i = from; i < capacity; i++)
{
arr[i] = new List;
}
}
void expand()
{
capacity *= 2;
List* *tempArr = new List*[capacity];
for (int i = 0; i < numOfElem; i++)
tempArr[i] = arr[i];
delete[] arr;
arr = tempArr;
initialize(numOfElem);
}
public:
Matrix()
{
capacity = 10;
numOfElem = 0;
arr = new List*[capacity];
}
~Matrix()
{
delete[] arr;
}
void append(List* newElement)
{
if (numOfElem >= capacity)
expand();
arr[numOfElem++] = newElement;
}
void set(int index, List* value)
{
arr[index] = value;
}
List* getAt(int index)
{
if (index < 0 || index >= numOfElem)
throw ("Out of bounds exception!!!");
return arr[index];
}
int getNumOfElem()
{
return numOfElem;
}
};
void transpose(Matrix tripleList)
{
for (int i = 0; i < tripleList.getNumOfElem(); i++)
{
{
List* list = new List;
(*list).copy(*(tripleListMatrix.getAt(i)));
int temp = (*list).getAt(0);
(*list).set(0, (*list).getAt(1));
(*list).set(1, temp);
(*list).displayList();
cout << "\n";
}
}
int main()
{
int m, n, input;
cout << "Please enter the number of rows and columns of the matrix :\n";
cin >> m >> n;
Matrix tripleListMatrix;
int k = 0;
cout << "Please enter the matrix : \n";
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cin >> input;
if (input != 0)
{
tripleListMatrix.append(new List);
(*(tripleListMatrix.getAt(k))).append(i + 1);
(*(tripleListMatrix.getAt(k))).append(j + 1);
(*(tripleListMatrix.getAt(k))).append(input);
k++;
}
}
}
cout << "The triple list of matrix is:\n";
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
(*(tripleListMatrix.getAt(i))).displayList();
cout << "\n";
}
cout << "\n\n";
//transpose(tripleListMatrix);
//the code below is the same as in the function transpose but transpose gives error
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
List* list = new List;
(*list).copy(*(tripleListMatrix.getAt(i)));
int temp = (*list).getAt(0);
(*list).set(0, (*list).getAt(1));
(*list).set(1, temp);
(*list).displayList();
//cout << "\t" << list;
cout << "\n";
}
cout << "\n\n";
//checking that tripleListMatrix is unchanged
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
(*(tripleListMatrix.getAt(i))).displayList();
cout << "\n";
}
return 0;
}
List* *arr;
When you call transpose(), it makes a copy Matrix because you're not passing by reference. That copy just has a copy of the address for your List, not it's own List object. When the destructor runs on the copy, it clears up the allocated memory, but the original Matrix object in main still points to that same memory. When that object goes away, its destructor tries to free the same memory again and that's bad.
You probably meant:
void transpose(Matrix const & tripleList)
So that no copy is made when calling transpose(), but you should also explicitly delete the copy construtor of Matrix so it cannot be called
Matrix(Matrix const &) = delete;
or make an explicit Matrix copy constructor that makes a deep copy of the memory.

Error with dynamic memory

I am trying to use the dynamic memory method instead of the vector method to add elements. Initially, the maximum size of the dynamic memory is set to 5. However, as soon as I try to increase more than the capacity of the current the dynamic memory, the elements of the 0th or 1st index loss their references.
The program works fine if I do not specify the size of the dynamic memory,
like: dynamic_memory = new int;. I am wondering why they lose their references
with the resize of the dynamic memory to more than the initial capacity.
PS: I am using Code::Block 16.01
Here is my program.
#include <iostream>
#include <cstdlib>
using namespace std;
class DynamicVector
{
public:
DynamicVector();
virtual ~DynamicVector();
void insertElement(int input);
int showCapacity();
int showSize();
void doubleSize(int * dynamic_memory);
friend ostream& operator << (ostream& outs, const DynamicVector obj);
private:
int * dynamic_memory;
int max_count; // this is similar to the capacity of the vector
int current_count; // this is similar to size of a vector
};
DynamicVector::DynamicVector()
{
max_count = 5;
dynamic_memory = new int[max_count];
current_count = 0;
}
DynamicVector::~DynamicVector()
{
delete [] dynamic_memory;
}
int DynamicVector::showCapacity(){
return max_count;
}
void DynamicVector::insertElement(int input)
{
if (current_count >= max_count)
doubleSize(dynamic_memory);
dynamic_memory[current_count] = input;
current_count++;
}
void DynamicVector::doubleSize(int * dynamic_memory){
int * tmp = new int[max_count];
for (int i = 0; i < max_count; i++)
tmp[i] = dynamic_memory[i];
delete [] dynamic_memory;
max_count = max_count * 2;
dynamic_memory = new int[max_count];
for (int i = 0; i < max_count; i++)
dynamic_memory[i] = tmp[i];
delete [] tmp;
}
int DynamicVector::showSize(){
return current_count;
}
ostream& operator <<(ostream& outs, const DynamicVector obj)
{
for (int i = 0; i < obj.current_count; i++)
outs << obj.dynamic_memory[i] << endl;
return outs;
}
int main()
{
DynamicVector v;
int numberOfIntendedElement = 11;
cout << "Previously, the capacity of vector was: " << v.showCapacity() << endl;
for (int i = 0; i < numberOfIntendedElement; i++)
v.insertElement(i);
cout << "The capacity of the new vector is: " << v.showCapacity() << endl;
cout << "The size of the new vector is: " << v.showSize() << endl;
cout << "The values in the dynamic vector are: \n" << v << endl;
return 0;
}
Result:
41107976
42075512
2
3
4
5
6
7
8
9
10
In
void doubleSize(int * dynamic_memory);
the dynamic_memory defined here shadows the member dynamic_memory; for comedic hi-jinks and undefined behaviour.
The local dynamic_memory is re-pointed at the new buffer, but the member dynamic_memory continues to point at the deleted original address after the function exits. This means that all subsequent inserts go into invalid memory, and Crom only knows what will happen after that.
Solution
Pass in nothing and use the member variable. Redefine the function as
void doubleSize();
Other problems are addressed in the comments and need to be fixed.
Thank you all for your valuable comments and suggestions, especially user4581301 for pointing a comedic hijinks and undefined behavior. After I redefined the function as void doubleSize(), it worked fine. Here is my final working code.
#include <iostream>
#include <cstdlib>
using namespace std;
class DynamicVector
{
public:
DynamicVector();
virtual ~DynamicVector();
void insertElement(int input);
int showCapacity();
int showSize();
void doubleSize();
friend ostream& operator << (ostream& outs, const DynamicVector obj);
private:
int * dynamic_memory;
int max_count; // this is similar to the capacity of the vector
int current_count; // this is similar to size of a vector
};
DynamicVector::DynamicVector()
{
max_count = 5;
dynamic_memory = new int[max_count];
current_count = 0;
}
DynamicVector::~DynamicVector()
{
delete [] dynamic_memory;
}
int DynamicVector::showCapacity(){
return max_count;
}
void DynamicVector::insertElement(int input)
{
if (current_count >= max_count)
doubleSize();
dynamic_memory[current_count] = input;
current_count++;
}
void DynamicVector::doubleSize(){
int * tmp = new int[max_count];
for (int i = 0; i < max_count; i++)
tmp[i] = dynamic_memory[i];
delete [] dynamic_memory;
max_count = max_count * 2;
dynamic_memory = new int[max_count];
for (int i = 0; i < max_count/2; i++)
dynamic_memory[i] = tmp[i];
delete [] tmp;
}
int DynamicVector::showSize(){
return current_count;
}
ostream& operator <<(ostream& outs, const DynamicVector obj)
{
for (int i = 0; i < obj.current_count; i++)
outs << obj.dynamic_memory[i] << endl;
return outs;
}
int main()
{
DynamicVector v;
int numberOfIntendedElement = 11;
cout << "Previously, the capacity of vector was: " << v.showCapacity() << endl;
for (int i = 0; i < numberOfIntendedElement; i++)
v.insertElement(i);
cout << "The capacity of the new vector is: " << v.showCapacity() << endl;
cout << "The size of the new vector is: " << v.showSize() << endl;
cout << "The values in the dynamic vector are: \n" << v << endl;
return 0;
}
Output
Previously, the capacity of vector was: 5
The capacity of the new vector is: 20
The size of the new vector is: 11
The values in the dynamic vector are:
0
1
2
3
4
5
6
7
8
9
10

Heap Corruption Detected C++ Custom Vector

Hey I am rehashing through a few old projects in a class I took and as I'm redoing this project I keep getting this error when my clear() function is called in the driver,
Heap Corruption Detected: after Normal block (#142)
CRT detected that the application wrote to memory after the end of the HEAP buffer
Here is my custom Vector class
#include "MyVector.h"
//insert header files
#include <iostream>
#include <string>
//setup access to necessary libraries
using namespace std;
MyVector::MyVector()
{
// initialize member data
size = 0;
capacity = 2;
//initialize new array
classArray = new int[capacity];
}
MyVector::MyVector(int maxCapacity)
{
// initialize member data
size = 0;
capacity = maxCapacity;
// initialize new array
classArray = new int[capacity];
}
MyVector::~MyVector()
{
if (classArray != NULL)
{
delete [] classArray;
classArray = NULL;
}
}
int MyVector::getSize()
{
return size;
}
int MyVector::getCapacity()
{
return capacity;
}
void MyVector::clear()
{
// delete the array
delete[] classArray;
// reinitialize the array
capacity = 2;
size = 0;
classArray = new int[capacity];
}
void MyVector::push_back(int n)
{
if (size > capacity)
{
// setup the special case of an array with 0 elements
if (size == 0)
{
clear();
}
else
{
// declare a temporary pointer and allocate a new array
capacity = capacity * 2;
int* tempArray = new int[capacity];
// copy the values from the old array to the temporary array
for (int i = 0; i < size; i++)
{
tempArray[i] = classArray[i];
}
// call the destructor
delete[] classArray;
// assign the classArray pointer to the new array
classArray = tempArray;
}
}
// pushback a new value to the array
classArray[size] = n;
// increment size
size++;
}
int MyVector::at(int n)
{
// check if n is within the bounds of the array
if (n >= size)
{
throw n;
}
// if not return the value of the index requested
else
{
return classArray[n];
}
}
and here is my driver code,
//insert header files
#include <iostream>
#include <string>
#include "MyVector.h"
//setup access to necessary libraries
using namespace std;
//declare constants
#pragma region Constants
const int TEST_VALUE1 = 21;
const int TEST_VALUE2 = 31;
const int TEST_VALUE3 = 41;
const int MAX = 12;
#pragma endregion
int main()
{
// Create a default vector
MyVector sam;
// push some data into sam
cout << "\nPushing three values into sam";
sam.push_back(TEST_VALUE1);
sam.push_back(TEST_VALUE2);
sam.push_back(TEST_VALUE3);
cout << "\nThe values in sam are: ";
// test for out of bounds condition here
// and test exception
for (int i = 0; i < sam.getSize() + 1; i++)
{
try
{
cout << sam.at(i) << " ";
}
catch (int badIndex)
{
cout << "\nOut of bounds at index " << badIndex << endl;
}
}
cout << "\n--------------\n";
// clear sam and display its size and capacity
sam.clear(); //********ERROR BEING THROWN HERE*********
cout << "\nsam has been cleared.";
cout << "\nSam's size is now " << sam.getSize();
cout << "\nSam's capacity is now " << sam.getCapacity() << endl;
cout << "---------------\n";
// Push 12 values into the vector - it should grow
cout << "\nPush 12 values into sam.";
for (int i = 0; i < MAX; i++)
sam.push_back(i);
cout << "\nSam's size is now " << sam.getSize();
cout << "\nSam's capcacity is now " << sam.getCapacity() << endl;
cout << "---------------\n";
cout << "\nTest to see if contents are correct...";
// display the values in the vector
for (int i = 0; i < sam.getSize(); i++)
{
cout << sam.at(i) << " ";
}
cout << "\n--------------\n";
cout << "\n\nTest Complete...";
cout << endl;
system("PAUSE");
return 0;
}
I've looked back and forth at my old project several times and I can't see why I am getting this error when I am trying to delete something. I mean it sounds like that usually happens when I am trying to allocate something that can't be allocated but not deleted?
Any help appreciated thanks!
Your push_back code can be reduced to:
if (size > capacity)
{
// resize
}
classArray[size] = n;
size++;
But note that you start with size == 0 and capacity == 2, then have three calls to push_back. On the third one, size == 2 and capacity == 2. size > capacity is still false, so you'll write into classArray[2] (without having resized) which is uninitialized memory. This is undefined behavior.
You want to check size >= capacity to resize.
Note that there's another serious problem with your class: you failed to write a copy constructor, so if you copied it, both copies would attempt to deallocate the same memory. See Rule of Three (updated in C++11 to Rule of Five).