Debug Assertion Fails On Dynamic Array - c++

So here is my working code for a simple dynamic array. This has to be a sample code for a very entry level data structure implementation:
#include <iostream>
using namespace std;
class AdvancedArray {
public:
AdvancedArray();
~AdvancedArray();
int get_size() const; // get the number of elements stored
double& at(int idx) const; // access the element at idx
void push_back(double d); // adds a new element
void remove(int idx); // remove the element at idx
void clear(); // delete all the data stored
void print() const;
private:
double* elements;
int size;
};
int main()
{
AdvancedArray* arr = new AdvancedArray();
cout << "The Array Size is: " << arr->get_size() << endl;
cout << "Pusing Values: 1.2, 2.1, 3.3, 4.5 in the Array. " << endl;
arr->push_back(1.2);
arr->push_back(2.1);
arr->push_back(3.3);
arr->push_back(4.5);
arr->print();
cout << "The Array Size is: " << arr->get_size() << endl;
cout << "The Element at Index 2 is: " << arr->at(2) << endl;
cout << "Deleting Values: 2.1 from the Array. " << endl;
arr->remove(1);
cout << "The Array Size is: " << arr->get_size() << endl;
arr->print();
cout << "Clearing the Array: " << endl;
arr->clear();
cout << "The Array Size is: " << arr->get_size() << endl;
arr->clear();
return 0;
}
AdvancedArray::AdvancedArray()
{
size = -1;
elements = new double[100]; //Maximum Size of the Array
}
AdvancedArray::~AdvancedArray()
{
delete[] elements;
}
int AdvancedArray::get_size() const
{
if(size < 0)
{
return 0;
}
return size;
}
double & AdvancedArray::at(int idx) const
{
if (idx < 100 && idx >= 0 && size > 0) {
return elements[idx];
}
cout << "Index Out of Bounds." << endl;
}
void AdvancedArray::push_back(double d)
{
if (size >= 100)
{
cout << "Overflow Condition. No More Space!" << endl;
}
else
{
elements[++size] = d;
cout << "Element Pushed In Stack Successfully!" << endl;
}
}
void AdvancedArray::remove(int idx)
{
if (size >= 100 || size < 0)
{
cout << "No Such Element Exists!" << endl;
}
else
{
for(int i = idx; i <size; i++)
{
elements[idx] = elements[idx + 1];
}
size--;
cout << "Element Deleted In Stack Successfully!" << endl;
}
}
void AdvancedArray::clear()
{
delete[] elements;
size = -1;
}
void AdvancedArray::print() const
{
cout << "[ ";
for(int i = 0; i <= size; i++)
{
cout << elements[i] << " ";
}
cout << "]" << endl;
}
So every time I try to run this I have the 2 problems:
What is wrong with my code? Why is the heap getting corrupted (I searched about the error code and that's all has to say)? Is my code doing some major access violations? I am using VS2015.

You do delete [] elements three times without setting elements to nullptr in between. That leads to undefined behavior the second time (and third) time.

When size == 99, the following piece of code attempts to access elements[100]:
if (size >= 100)
{
cout << "Overflow Condition. No More Space!" << endl;
}
else
{
elements[++size] = d;
cout << "Element Pushed In Stack Successfully!" << endl;
}
You need to change ++size to size++.

Related

C++ Array values being altered at element 4 after throwing exception

The requirements for the program state that the try/catch must be placed in the main.cpp as below:
cout << "printing the array element by element using: int getElement(int);" << endl;
cout << "(going one too far to test out of range)" << endl;
for(int i=0; i<=LISTSIZE; i++){
try{
elementResult = mylist.getElement(i);
cout << elementResult << endl;
} catch(int e){
cout << "Error: Index out of range." << endl;
}
}
cout << endl;
When it accesses the method:
int MyList::getElement(int passedIndex){
if((passedIndex < 0) || (passedIndex > length -1)){
throw 0;
}
return array[passedIndex];
}
It doesn't seem to matter which variation of throwing I use, my array gets destroyed afterward. It works fine if it stays within bounds, or I work it to not throw from the method (doing the error checking elsewhere), but the requirements state that it has to be that way, so I must be missing something. Full code below:
main.h:
#ifndef MAIN_H
#define MAIN_H
/***********************************
* DO NOT MODIFY THIS FILE OTHER THAN
* TO ADD YOUR COMMENT HEADER
***********************************/
#include <iostream> /* cout, endl */
#include "mylist.h"
#include <stdexcept>
#define LISTSIZE 10
using std::cout;
using std::endl;
int elementResult;
#endif /* MAIN_H */
main.cpp:
#include "main.h"
int main(int argc, char** argv) {
/***********************************
* DO NOT MODIFY THIS FILE OTHER THAN
* TO ADD YOUR COMMENT HEADER AND
* UNCOMMENT THINGS AS YOU COMPLETE
* THE FUNCTIONALITY OF YOUR LIST OBJECT
***********************************/
/* This will create a "list" of size LISTSIZE
* and initialize it to all zeros */
cout << "create and initialize mylist" << endl;
MyList mylist(LISTSIZE);
mylist.printArray();
cout << endl;
/* This will set the list to all 50 */
cout << "set mylist to all 50" << endl;
mylist.setArray(50);
mylist.printArray();
cout << endl;
/* This will fail and set the array to the
* default random 1-10 values */
cout << "attempt to set to random numbers -2 to 4" << endl;
mylist.setRandom(-2,4);
mylist.printArray();
cout << endl;
/* This will fail and set the array to the
* default random 1-10 values */
cout << "attempt to set to random numbers 4 to 4" << endl;
mylist.setRandom(4,4);
mylist.printArray();
cout << endl;
/* This will succeed and set the array to the
* random 1-100 values */
cout << "attempt to set to random numbers 1 to 100" << endl;
mylist.setRandom(1,100);
mylist.printArray();
cout << endl;
/* This will succeed and set the array to the
* random 500-1000 values */
cout << "attempt to set to random numbers 500 to 1000" << endl;
mylist.setRandom(1000,500);
mylist.printArray();
cout << endl;
/* These next two sets will succeed and set the 1st and last
* elements to 1000 and 2000 respectively */
if(mylist.setElement(1000, 0)){
cout << "Element Set" << endl;
} else {
cout << "Element NOT Set" << endl;
}
if(mylist.setElement(2000, LISTSIZE-1)){
cout << "Element Set" << endl;
} else {
cout << "Element NOT Set" << endl;
}
mylist.printArray();
cout << endl;
/* These next two sets will fail and leave the array unmodified */
if(mylist.setElement(9999, -1)){
cout << "Element Set" << endl;
} else {
cout << "Element NOT Set" << endl;
}
if(mylist.setElement(9999, LISTSIZE)){
cout << "Element Set" << endl;
} else {
cout << "Element NOT Set" << endl;
}
mylist.printArray();
cout << endl;
cout << "Testing new and/or modified code..." << endl << endl;
cout << "printing the array element by element using: int getElement(int);" << endl;
cout << "(going one too far to test out of range)" << endl;
for(int i=0; i<=LISTSIZE; i++){
try{
elementResult = mylist.getElement(i);
cout << elementResult << endl;
} catch(int e){
cout << "Error: Index out of range." << endl;
}
}
cout << endl;
mylist.printArray();
cout << "attempting to get element 4000 using: int getElement(int);" << endl;
try{
cout << mylist.getElement(4000) << endl;
} catch(int e){
cout << "Error: Index out of range." << endl;
}
cout << endl;
cout << "printing the array element by element using: int getElement(int,int*);" << endl;
cout << "(going one too far to test out of range)" << endl;
for(int i=0; i<=LISTSIZE; i++){
if(mylist.getElement(i, &elementResult)){
cout << elementResult << endl;
} else {
cout << "Error: Index out of range." << endl;
}
}
cout << endl;
cout << "attempting to get element 4000 using: int getElement(int,int*);" << endl;
if(mylist.getElement(4000, &elementResult)){
cout << elementResult << endl;
} else {
cout << "Error: Index out of range." << endl;
}
return 0;
}
mylist.h:
#ifndef MYLIST_H
#define MYLIST_H
#include <iostream> /* cout, endl */
#include <stdlib.h> /* srand, rand, atoi */
#include <time.h> /* time */
#include <stdexcept>
// you can add libraries if you need them, but you shouldn't
// DO NOT MODIFY THESE DEFINES
#define RMIN 1
#define RMAX 10
#define DEFAULT_SIZE 10
using std::cout;
using std::endl;
class MyList {
public:
// DO NOT MODIFY THESES NEXT TWO
MyList(int); // constructor
~MyList(); // destructor
int getElement(int);
void setArray(int);
bool setElement(int, int);
void setRandom(int, int);
void printArray();
bool getElement(int, int*);
private:
// these are the only attributes allowed
// DO NOT ADD OR MODIFY THEM
int length;
int *array;
};
#endif //MYLIST_H
mylist.cpp:
#include "mylist.h"
// constructor
MyList::MyList(int size) {
srand(time(NULL)); // call only once!
if(size < 1){
size = DEFAULT_SIZE;
}
MyList::length = size;
MyList::array = new int(size);
setArray(0);
}
// destructor
MyList::~MyList() {
//delete[] MyList::array;
}
void MyList::printArray() {
cout << "[";
for (int i = 0; i < length; i++){
if (i == length - 1){
cout << array[i];
}else{
cout << array[i] << " ";
}
}
cout << "]" << endl;
}
void MyList::setArray(int setArrayTo){
for (int i = 0; i < length; i++){
MyList::array[i] = setArrayTo;
}
}
void MyList::setRandom(int numOne, int numTwo){
bool isValidRandom = true;
int randMin, randMax;
if((numOne < RMIN) || (numTwo < RMIN) || (numOne == numTwo)){ isValidRandom = false; }
if(isValidRandom == true){
if(numTwo < numOne){
randMin = numTwo;
randMax = numOne;
} else {
randMin = numOne;
randMax = numTwo;
}
} else {
randMin = RMIN;
randMax = RMAX;
}
for(int i = 0;i < length; i++){
MyList::array[i] = rand() % randMax + randMin;
}
}
bool MyList::setElement(int passedValue, int arrayIndex){
bool isInRange = true;
if ((arrayIndex < 0)||(arrayIndex > length - 1)){
isInRange = false;
}
if (isInRange == true){
MyList::array[arrayIndex] = passedValue;
}
return isInRange;
}
int MyList::getElement(int passedIndex){
if((passedIndex < 0) || (passedIndex > length -1)){
throw 0;
}
return array[passedIndex];
}
bool MyList::getElement(int passedIndex, int *iPtr){
bool isItValid = true;
if((passedIndex >= 0) && (passedIndex < length)){
*iPtr = MyList::array[passedIndex];
} else {
isItValid = false;
}
return isItValid;
}
Output

C++ -Problems in Stacking an array

I've been trying to figure out why my code isn't working correctly for the past few hours. Everything looks perfectly fine to me unless it's something I don't know about. I have asked my professor, but he can't seem to figure it out either. This code will completely ignore the if else statement in the push member function and will keep pushing after reaching the limit (in this case it's 5 elements). When it goes over the 5th element, and I check for the top, it shows the first implementation (element 0). I tried changing around my code by switching the member functions outside the class via scope resolution, but it's still no use. A different set of eyes would be greatly appreciated.
#include <iostream>
#include <cctype>
using namespace std;
class Stack
{
private:
static const int size = 5;
double myarr[size];
int t;
public:
Stack() { t = -1; }
void push(double element);
void pop();
void top();
void menu();
};
void Stack::push(double element)
{
if (t < size) {
t++;
myarr[t] = element;
}
else
cout << "Stack Limit Reach !!!" << endl;
}
void Stack::pop()
{
if (t >= 0) {
cout << "Element : " << myarr[t] << " was popped off the Stack " << endl;
t--;
}
else
cout << "No more elemnts in the Stack !!!" << endl;
}
void Stack::top()
{
if (t >= 0) {
cout << "Element : " << myarr[t] << " is at the top of the Stack " << endl;
}
else
cout << "No more elemnts in the Stack !!!" << endl;
}
void Stack::menu()
{
char choice = 'y';
int pick;
double elem;
while (toupper(choice) == 'Y');//while(choice == 'y' || choice == 'Y');
{
cout << "1. Push" << endl;
cout << "2. Pop" << endl;
cout << "3. Top" << endl;
cout << "4. Exit" << endl;
cin >> pick;
switch (pick)
{
case 1:
cout << "Enter the element: ";
cin >> elem;
cout << endl;
push(elem);
break;
case 2:
pop();
break;
case 3:
top();
break;
case 4:
choice = 'N';
break;
default:
cout << "Please select 1-4" << endl;
}
system("pause");
}
}
int main()
{
Stack obj;
obj.menu();
};
In your example code, the stack's size is 5 (which means array myarr has valid indices 0 through 4).
void Stack::push(double element)
{
if (t < size) {
t++;
myarr[t] = element;
}
else
cout << "Stack Limit Reach !!!" << endl;
}
Consider the case when t here is 4. The if tests true, so the block to add to myarr is entered. First thing that happens is you increment t, which is now 5. Then you use that as the index to store the value into myarr, which is out of bounds.
Try something like:
void Stack::push(double element)
{
if (t < size) {
myarr[t++] = element;
}
else
cout << "Stack Limit Reach !!!" << endl;
}
You are allowing 6 elements to be pushed onto the stack, and there's only room for 5.
Change:
if (t < size) {
t++;
to:
if (t < size-1) {
t++;
I understood your problem when you are searching for the top element you are not getting because whenever the stack becomes full for ex:-
assume you are inserting(below mentioned code) 5th element in 4th index it will be inserted and the value of t get incremented to 5 due to t++.
void Stack::push(double element)
{
if (t < size) {
t++;
myarr[t] = element;
}
else
cout << "Stack Limit Reach !!!" << endl;
}
but at the same time when you call top() function it checks for the index, and obviously 5 is greater that 0 so it enters the loop but index 5 contains '\0'
Character so there is an ambiguity with compiler
void Stack::top()
{
if (t >= 0) {
cout << "Element : " << myarr[t] << " is at the top of the Stack " << endl;
}
else
cout << "No more elemnts in the Stack !!!" << endl;
}
So the change that is required for the above code is just put a if statement by saying the compiler that if the stack is full then decrement t value by 1
void Stack::top()
{
if (t >= 0) {
if(t==size){t--;}
cout << "Element : " << myarr[t] << " is at the top of the Stack " << endl;
}
else
cout << "No more elemnts in the Stack !!!" << endl;
}
This may give you correct result
You skip myarr[0] then 5th element is saved to myarr[5] that is 6th element in myarr! (Accessing to elements of an array by index is zero based in C++)
Change:
Stack() { t = -1; }
to:
Stack() { t = 0; }
and
if (t < size) {
t++;
myarr[t] = element;
to:
if (t < size) {
myarr[t++] = element;

Errors within Main program using classes

I just have a few errors of the same type in my main program. My college professor is not answering my emails so I have to resort to asking you guys. In my main program I have several errors somewhat similar to this: "request for member which is of non-class type." Program01 is basically testing every function in ListType.h, OListType.h, and UListType.h to make sure everything works correctly. Any help you can provide in a timely fashion will be appreciated.
Here is ListType.h:
#ifndef LISTTYPE_H_INCLUDED
#define LISTTYPE_H_INCLUDED
#include <iostream>
class ListType {
public:
ListType(size_t=10);
ListType(const ListType&);
virtual ~ListType();
virtual bool insert(int)=0;
virtual bool eraseAll();
virtual bool erase(int)=0;
virtual bool find(int) const=0;
size_t size() const;
bool empty() const;
bool full() const;
friend std::ostream& operator << (std::ostream&, const ListType&);
const ListType& operator= (const ListType&);
protected:
int *items;
size_t capacity;
size_t count;
};
#endif // LISTTYPE_H_INCLUDED
Here is ListType.cpp:
#include "ListType.h"
ListType::ListType (size_t a) {
capacity = a;
count = 0;
items = new int [capacity];
}
ListType::ListType(const ListType& newlist) {
capacity = newlist.capacity;
count = newlist.count;
items = new int [capacity];
for (size_t i = 0; i < count; ++i)
items[i] = newlist.items[i];
}
ListType::~ListType() {
delete [] items;
}
bool ListType::eraseAll() {
count = 0;
return 0;
}
size_t ListType::size() const {
return (count);
}
bool ListType::empty() const {
return (count == 0);
}
bool ListType::full() const {
return (count == capacity);
}
std::ostream& operator << (std::ostream& out, const ListType& my_list) {
if (!my_list.empty()) {
for (size_t i = 0; i < my_list.count; ++i){
out << my_list.items[i] << ',';
}
}
return out;
}
const ListType& ListType::operator= (const ListType& rightObject) {
if (this != & rightObject) {
delete [] items;
capacity = rightObject.capacity;
count = rightObject.count;
items = new int[capacity];
for (size_t i = 0; i < count; ++i) {
items[i] = rightObject.items[i];
}
}
return *this;
}
Here is UListType.h:
#ifndef ULISTTYPE_H_INCLUDED
#define ULISTTYPE_H_INCLUDED
#include <iostream>
class UListType: public ListType {
public:
UListType(size_t=10);
bool insert(int);
bool erase(int);
bool find(int) const;
};
#endif // ULISTTYPE_H_INCLUDED
Here is UListType.cpp:
#include "ListType.h"
#include "UListType.h"
UListType::UListType (size_t c): ListType(c) {}
bool UListType::insert(int item) {
if (full()) {
int *newitems;
capacity *=2;
newitems = new int[capacity];
for (size_t i =0; i < count; ++i){
newitems[i] = items[i];
}
delete [] items;
items = newitems;
}
items[count++] = item;
return true;
}
bool UListType::erase(int item) {
bool result = false;
size_t i=0;
while ( i < count && items [i] != item) {
++i;
}
if (i < count) {
items[i] = items[-- count];
result = true;
}
return result;
}
bool UListType::find(int item) const {
size_t i = 0;
while (i < count && items [i] != item) {
++i;
}
return i < count;
}
Here is OListType.h:
#ifndef OLISTTYPE_H_INCLUDED
#define OLISTTYPE_H_INCLUDED
#include <iostream>
class OListType: public ListType {
public:
OListType(size_t=10);
bool insert(int);
bool erase(int);
bool find(int) const;
};
#endif // OLISTTYPE_H_INCLUDED
Here is OListType.cpp:
#include "ListType.h"
#include "OListType.h"
OListType::OListType(size_t c): ListType(c) {}
bool OListType::insert(int item) {
size_t i = count;
if (full()) {
int *newitems;
capacity *=2;
newitems = new int[capacity];
for(size_t j=0; j < count; ++j) {
newitems[j] = items[i];
}
delete [] items;
items = newitems;
}
while (i > 0 && items[i-1] > item){
items[count++] = item;
}
return true;
}
bool OListType::erase(int item) {
bool found=false;
size_t i=0, j= count-1, mid;
while (i <= j && !(found)){
mid = (i + j)/2;
if (item < items [mid])
j = mid - 1;
else if (item > items [mid])
i = mid + 1;
found = items [mid] == item;
}
if (found) {
for (i = mid; i < count - 1; ++i) {
items [i] = items [i +1];
}
--count;
}
return found;
}
bool OListType::find (int item) const {
bool found=false;
size_t i=0, j= count-1, mid;
while (i <= j && !(found)){
mid = (i + j)/2;
if (item < items [mid])
j = mid - 1;
else if (item > items [mid])
i = mid + 1;
found = items [mid] == item;
}
return found;
}
Here is Program01.cpp:
#include "ListType.h"
#include "UListType.h"
#include "OListType.h"
#include <iostream>
using namespace std;
int main() {
OListType list[5] = {165, 16, 118, 212, 104};
UListType ranlist[10] = {243, 300, 154, 153, 592, 124, 195, 217, 289, 405};
UListType UListAssignmentTest;
OListType OListAssignmentTest;
cout << "The Ordered List before operations:" << endl;
cout << list << endl << endl;
if(list.empty()) **<-- HERE BE THE ERROR**
cout << "The list is empty, therefore it is true.";
else
cout << "The list is full or partially full, therefore it is false";
cout << endl << endl;
if(list.full())
cout << "The list is full, therefore it is true.";
else
cout << "The list is partially full or empty, therefore it is false";
cout << endl << endl;
list.insert(25);
cout << endl << endl;
cout << "The Ordered list after Insert:" << endl;
cout << list << endl << endl;
list.find(25);
cout << endl << endl;
list.find(30);
cout << endl << endl;
list.erase(25);
cout << endl << endl;
cout << "The Ordered List after Erase:" << endl;
cout << list << endl << endl;
cout << "The Unordered List before operations:" << endl;
cout << ranlist << endl << endl;
if(ranlist.empty())
cout << "The list is empty, therefore it is true.";
else
cout << "The list is full or partially full, therefore it is false";
cout << endl << endl;
if(ranlist.full())
cout << "The list is full, therefore it is true.";
else
cout << "The list is partially full or empty, therefore it is false";
cout << endl << endl;
ranlist.insert(25);
cout << endl << endl;
cout << "The Unordered List after Insert:" << endl;
cout << ranlist << endl << endl;
ranlist.find(25);
cout << endl << endl;
ranlist.find(30);
cout << endl << endl;
ranlist.erase(25);
cout << endl << endl;
cout << "The Unordered List after Erase:" << endl;
cout << ranlist << endl << endl;
cout << "Testing Ordered List Assignment Operator" << endl;
OListAssignmentTest = list;
cout << OListAssignmentTest << endl << endl;
cout << "Testing Unordered List Assignment Operator" << endl;
UListAssignmentTest = ranlist;
cout << UListAssignmentTest << endl << endl
cout << "Testing Ordered List Copy Constructor" << endl;
OListType OListVariable = list;
cout << OListVariable << endl << endl;
cout << "Testing Unordered List Copy Constructor" << endl;
UListType UListVariable = ranlist;
cout << UListVariable << endl << endl;
cout << "Testing Erase All for OList" << endl;
list.eraseAll();
cout << "OList values now: " << list.empty() << endl << endl;
cout << "Testing Erase All for UList" << endl;
ranlist.eraseAll();
cout << endl << "UList values now: " << ranlist.empty() << endl;
return 0;
}
OListType list[5] = {165, 16, 118, 212, 104};
This line declares an array of 5 OListType types. This doesn't seem correct.
You want to declare one OLIstType and insert 5 values into it. If not, please clarify what that line is supposed to denote.
Here is probably what you are supposed to do:
OListType list;
list.insert(165);
list.insert(16); // etc...

Changing an array class to hold a dynamic array

everything i have read says this should be easy and that you just add these three lines
typedef double* DoublePtr;
DoublePtr p;
p = new double [10]
but where do i add this code? Everything i have tried just breaks my program what am I missing? I tried a set function to set the value of max size but it didn't work either
does anyone know how to do this?
#include<iostream>
using namespace std;
const int MAX_SIZE = 50;
class ListDynamic
{
public:
ListDynamic();
bool full();
int getSize();
void addValue(double value);
double getValue(int index);
double getLast();
void deleteLast();
friend ostream& operator <<(ostream& out, const ListDynamic& thisList);
private:
double listValues[MAX_SIZE];
int size;
};
int main()
{
double value;
ListDynamic l;
cout << "size of List " << l.getSize() << endl;
cout << "New size of List " << l.getSize() << endl;
cout << "First Value: " << l.getValue(0) << endl;
cout << "Last Value: " << l.getLast() << endl;
cout << "deleting last value from list" << endl;
l.deleteLast();
cout << "new list size " << l.getSize() << endl;
cout << "the list now contains: " << endl << l << endl;
system("pause");
return 0;
}
ListDynamic::ListDynamic()
{
size = 0;
}
bool ListDynamic::full()
{
return (size == MAX_SIZE);
}
int ListDynamic::getSize()
{
return size;
}
void ListDynamic::addValue(double value)
{
if (size < MAX_SIZE)
{
listValues[size] = value;
size++;
}
else
cout << "\n\n*** Error in ListDynamic Class: Attempting to add value past max limit.";
}
double ListDynamic::getValue(int index)
{
if (index < size)
return listValues[index];
else
cout << "\n\n*** Error in ListDynamic Class: Attempting to retrieve value past current size.";
}
double ListDynamic::getLast()
{
if (size > 0)
return getValue(size - 1);
else
cout << "\n\n*** Error in ListDynamic Class: Call to getLast in Empty List.";
}
void ListDynamic::deleteLast()
{
if (size > 0)
size--;
else
cout << "\n\n*** Error in ListDynamic Class: Call to deleteLast in Empty List.";
}
ostream& operator <<(ostream& out, const ListDynamic& thisList)
{
for (int i = 0; i < thisList.size; i++)
out << thisList.listValues[i] << endl;
return out;
}
You need to change listValues to a double*
double* listValues;
And when you add a value greater than the size, you'll need to reallocate the array your array and copy the elements of the former array to the new one. For example:
void ListDynamic::addValue(double value)
{
if (full())
{
double* temp = new double[size];
std::copy(listValues, listValues + size, temp);
delete[] listValues;
listValues = new double[size + 1];
std::copy(temp, temp + size, listValues);
listValues[size] = value;
delete[] temp;
} else
{
listValues[size++] = value;
}
}

how to use exceptions and pointers in a vector class

I have this vector class, and I was provided with a driver to test the class. Most of it seems to work fine but I think there is something wrong with the exceptions part (which I haven't quite fully understood)
Here is the code for the class .cpp file
int myVector::at(int i)
{
if(i<vsize)
return array[i];
throw 10;
}
and here is the driver code
#include "myVector.h"
#include <iostream>
using namespace std;
int main()
{
// Create a default vector (cap = 2)
myVector sam;
// push some data into sam
cout << "\nPushing three values into sam";
sam.push_back(21);
sam.push_back(31);
sam.push_back(41);
cout << "\nThe values in sam are: ";
// test for out of bounds condition here
for (int i = 0; i < sam.size( ) + 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( );
cout << "\nsam has been cleared.";
cout << "\nSam's size is now " << sam.size( );
cout << "\nSam's capacity is now " << sam.capacity( ) << endl;
cout << "---------------\n";
// Push 12 values into the vector - it should grow
cout << "\nPush 12 values into sam.";
for (int i = 0; i < 12; i++)
sam.push_back(i);
cout << "\nSam's size is now " << sam.size( );
cout << "\nSam's capcacity is now " << sam.capacity( ) << endl;
cout << "---------------\n";
cout << "\nTest to see if contents are correct...";
// display the values in the vector
for (int i = 0; i < sam.size( ); i++)
{
cout << sam.at(i) << " ";
}
cout << "\n--------------\n";
cout << "\n\nTest Complete...";
cout << endl;
system("PAUSE");
return 0;
}
Any help is appreciated. Thanks
The driver that you have provided:
try {
cout << sam.at(i) << " ";
}
catch(int badIndex) {
cout << "\nOut of bounds at index " << badIndex << endl;
}
expects that int will be thrown (a bit weird design, but well... this is the code that will use your class...). Your implementation of at() might look like this:
int& myVector::at(int i) throw(int) {
if (i < vsize)
return array[i];
throw i;
}
just try to follow one simple rule: throw by value, catch by reference.
Also note that you have a pointer:
private:
int* array;
which points to dynamically allocated memory allocated in constructor and copy constructor and freed in destructor :
myVector::myVector(int i)
{
...
array = new int[maxsize];
}
myVector::myVector(const myVector& v)//copy constructor
{
...
array =new int[maxsize];
}
myVector::~myVector()
{
delete[] array;
}
But how about the assignment operator ? See What is The Rule of Three?
Your stop condition of for loop ends it one element after the last one (i.e. you cannot access 4th element of sam vector because there are only three elements).
std::vector::at throws std::out_of_range exception in such situation (see: http://en.cppreference.com/w/cpp/container/vector/at), not int one. So you should change your exception handling part to something like this:
#include <exception>
try
{
cout << sam.at(i) << " ";
}
catch(std::out_of_range exc)
{
cout << "\nOut of bounds at index " << exc.what() << endl;
}