I have to finish a prompt tonight for my coding class, and I believe I am writing this incorrectly. I have reviewed other stackoverflow answers, but I still lack the understanding necessary to correctly solve this. This is part of a bigger project, so I have included all code in case another function is causing this error, but in my testing only the Ballot class is giving me errors.
In getVote, if the parameter is within the used portion of the array,
return the Voter pointer that corresponds with that position.
This is supposed to be tested with:
Ballot ballot1("WI-643UWO");
const Vote *vote3 = ballot1.getVote(2);
cout << vote3 << "\n";
//header file
pragma once
#include <string>
using namespace std;
class Election {
private:
string office;
string firstCanidiateName;
string secondCanidiateName;
public:
Election(string office2, string firstCanidiateName2, string secondCanidiateName2);
string getOffice() const;
string getCandidate1() const;
string getCandidate2() const;
};
class Vote {
private:
string vOffice;
string canidiateName;
bool voteMadeInPerson;
public:
Vote(string vOffice2, string canidiateName2, bool voteMadeInPerson2);
string getOffice() const;
string getCandidate() const;
bool wasInPerson() const;
};
class Ballot {
private:
string voterID;
int votesStored;
Vote* votePointer[6];
public:
Ballot();
Ballot(string voterID2);
~Ballot();
string getVoterId() const;
int getVoteCount() const;
const Vote* getVote(int votePosition) const;
void recordVote(string office, string candidateName, bool voteInPerson);
int countInPersonVotes();
int findVote(string office) const;
};
//functions file
#include "p3.h"
#include <string>
using namespace std;
Election::Election(string office2, string firstCanidiateName2, string secondCanidiateName2) {
office = office2;
firstCanidiateName = firstCanidiateName2;
secondCanidiateName = secondCanidiateName2;
}
string Election::getOffice() const {
return office;
}
string Election::getCandidate1() const {
return firstCanidiateName;
}
string Election::getCandidate2() const {
return secondCanidiateName;
}
string Vote::getOffice() const {
return vOffice;
}
string Vote::getCandidate() const {
return canidiateName;
}
bool Vote::wasInPerson() const {
return voteMadeInPerson;
}
Vote::Vote(string vOffice2, string canidiateName2, bool voteMadeInPerson2) {
if (vOffice2.empty() == true) {
vOffice2 = "Unknown";
}
vOffice = vOffice2;
if (canidiateName2.empty() == true) {
canidiateName2 = "Write In";
}
canidiateName = canidiateName2;
voteMadeInPerson = voteMadeInPerson2;
}
string Ballot::getVoterId() const {
return voterID;
}
int Ballot::getVoteCount() const {
return votesStored;
}
const Vote* Ballot::getVote(int votePosition) const {
Vote* out;
if (votePosition > -1 && votePosition < votesStored) {
//unsure if this is proper syntax -- will need testing
out = votePointer[votePosition];
return out;
}
else {
out = nullptr;
return out;
}
}
void Ballot::recordVote(string office, string candidateName, bool voteInPerson) {
if ((votesStored + 1) < 6) {
int x = findVote(office);
if (x != -1) {
Vote* z = new Vote(office, candidateName, voteInPerson);
votePointer[votesStored] = z;
++votesStored;
}
}
}
int Ballot::countInPersonVotes() {
int count = 0;
for (int i = 0; i < votesStored; ++i) {
bool x = false;
x = votePointer[i]->wasInPerson();
if (x == true) {
count++;
}
}
return count;
}
int Ballot::findVote(string office) const {
//test to make sure this logically works
int i = 0;
bool matchCheck = false;
for (i = 0; i < votesStored; ++i) {
if (votePointer[i]->getOffice() == office) {
matchCheck = true;
return i + 1;
}
}
if (matchCheck == false) {
return -1;
}
}
Ballot::Ballot(string voterID2) {
voterID = voterID2;
votesStored = 0;
}
Ballot::Ballot() {
voterID = "Invalid ID";
votesStored = 0;
}
Ballot::~Ballot() {
/**this is what the prompt asks for, technically.
the book details that this can be achieved in a more simple matter --
using the delete[] operator.
*/
for (int i = 0; i < 6; ++i) {
delete votePointer[i];
}
}
Any help would be appreciated - I am unsure where I am messing up here. I seem to be getting a lot of read access violation errors, but we haven't touched on debugging, so I'm not necessarily sure how to identify what I did wrong. Furthermore, my functions did seem to work initially until I tried fixing it, and now it gives me a read-error almost instantly, which is concerning. And lastly - I am new to pointers, so there is a very high chance I messed up there. Thanks for any advice.
Related
I'm working on an x/y coordinate maze solving project.
I have a problem with my Maze object, whose data members are locations which also are objects of int row, int col and enum Direction {right down left up done}.
When I run my debugger, error messages come up that say "invalid use of this outside of non static member function" on the Maze object.
Why is this coming up? I don't understand how this message is showing if I'm not using any this->endLocation statement anywhere in my Maze.cpp file.
#include "maze-proj1.h"
using namespace std;
Maze::Maze() {
validLocationCount = 0;
validLocations = NULL;
startLocation = endLocation;
}
Maze::~Maze() {
if(validLocations != NULL) {
delete [] validLocations;
}
validLocations = NULL;
validLocationCount = 0;
}
Location Maze::getStartLocation() const {
return startLocation;
}
bool Maze::isValidLocation(const Location &loc) const {
int count = 0;
for (int i = 0; i < validLocationCount; i++) {
if (loc == validLocations[i]) {
count++;
}
}
if (count == validLocationCount){
return true;
}
return false;
}
bool Maze::isEndLocation(const Location &loc) const {
return loc == endLocation;
}
istream &operator>>(istream &is, Maze &m) {
is >> m.validLocationCount;
m.validLocations = new Location[m.validLocationCount];
for(int i = 0; i < m.validLocationCount; i++){
is >> m.validLocations[i];
}
is >> m.startLocation;
is >> m.endLocation;
}
class Maze {
public:
Maze(void);
~Maze();
Location getStartLocation(void) const;
bool isValidLocation(const Location &loc) const;
bool isEndLocation(const Location &loc) const;
friend istream &operator>>(istream &is, Maze &m);
private:
Maze(const Maze &) { assert(false); }
const Maze &operator=(const Maze &)
{ assert(false); return *this; }
int validLocationCount;
Location *validLocations;
Location startLocation, endLocation;
};
#endif
Code actually runs fine for me, but I have to submit it to someone, and in return I get an error which I cannot perceive.
The following error is:
munmap_chunk(): invalid pointer (core dumped)
The error appears to be occurring in method named: loadLuggage. I have also checked the code with Valgrind, but no possible leaks were detected. Perhaps I was not compiling it correctly.
#include <iostream>
#include <string>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <cstdlib>
#include <ctime>
using namespace std;
template<typename T>
int izbrisiVrsto(queue<T> &queue) {
int numberOfRemoved = 0;
while (!queue.empty()) {
queue.pop();
numberOfRemoved++;
}
return numberOfRemoved;
}
template<typename T>
int deleteStack(stack<T> &stack) {
int numberOfDeleted = 0;
while (!stack.empty()) {
stack.pop();
numberOfDeleted++;
}
return numberOfDeleted;
}
class Traveler {
private:
string name;
string surname;
int age;
string emso; //used as ID
public:
Traveler(const string &name, const string &surname, int age, const string &emso)
: name(name), surname(surname), age(age), emso(emso) {
}
~Traveler() {}
string getName() const {
return name;
}
void setName(const string &name) {
this->name = name;
}
string getSurname() const {
return surname;
}
void setSurname(const string &surname) {
this->surname = surname;
}
int getAge() const {
return age;
}
void setAge(int age) {
this->age = age;
}
string getEmso() const {
return emso;
}
void setEmso(const string &emso) {
this->emso = emso;
}
};
enum TravelClass {
ECONOMY,
BUSINESS
};
class Luggage {
private:
int luggageID;
public:
Luggage(int id) : luggageID(id) {}
~Luggage() {}
int getLuggageID() const {
return luggageID;
}
void setLuggageID(int id) {
this->luggageID = id;
}
};
class BoardingTicket {
private:
Traveler traveler;
TravelClass travelClass;
Luggage luggage;
public:
BoardingTicket(const Traveler &traveler, const TravelClass &pr, const Luggage &luggage)
: traveler(traveler), travelClass(pr), luggage(luggage) {
}
~BoardingTicket() {}
Traveler getTraveler() const {
return traveler;
}
void setTraveler(const Traveler &traveler) {
this->traveler = traveler;
}
TravelClass getTravelClass() const {
return travelClass;
}
void setTravelClass(TravelClass travelClass) {
this->travelClass = travelClass;
}
Luggage getLuggage() const {
return luggage;
}
void setLuggage(const Luggage &luggage) {
this->luggage = luggage;
}
};
class Plane {
private:
int id; //plane ID
public:
stack<stack<Luggage> > trunk; //stack of luggage on plane = all travelers luggage
private:
unsigned int maxNumberOfLuggage; //number of maxium luggage on the heap
public:
Plane(int id, unsigned int maxNumberOfLuggage) :
id(id),
maxNumberOfLuggage(maxNumberOfLuggage) {
}
~Plane() {}
//get/set metode
int getID() const {
return id;
}
void setID(int id) {
this->id = id;
}
unsigned int getMaxNumberOfLuggage() const {
return maxNumberOfLuggage;
}
void setMaxNumberOfLuggage(unsigned int maxNumberOfLuggage) {
this->maxNumberOfLuggage = maxNumberOfLuggage;
}
void loadLuggage(queue<Luggage> &luggages) {
//TODO: implementation
while (luggages.empty() == false) {
stack<Luggage> pallet; //certain number of luggage on pallet
for (int i = 0; i < this->maxNumberOfLuggage; i++) {
Luggage luggage = luggages.front();
pallet.push(luggage);
luggages.pop();
}
this->trunk.push(pallet); //loading in trunk
}
}
queue<Luggage> unloadLuggage() {
//TODO: implementation
queue<Luggage> unloadingLuggage;
while (trunk.empty() == false) {
stack<Luggage> pallet = trunk.top();
trunk.pop();
for (int i = 0; i < pallet.size(); i++) {
unloadingLuggage.push(pallet.top());
pallet.pop();
}
}
return unloadingLuggage; //HACK: dummy return
}
};
class Airline {
public:
queue<BoardingTicket> boardingPeople; //people waiting to board on a plane
queue<Luggage> unloadedLuggage;
Airline() {}
~Airline() {}
void split(queue<BoardingTicket> &travelers, queue<BoardingTicket> &businessTravelers,
queue<BoardingTicket> &economyTravelers) {
//TODO: implementation
while (travelers.empty() == false) {
BoardingTicket traveler = travelers.front(); //izbira prvega potnika
if (traveler.getTravelClass() == ECONOMY) {
economyTravelers.push(traveler);
} else if (traveler.getTravelClass() == BUSINESS) {
businessTravelers.push(traveler);
}
travelers.pop(); //traveler vkrcan
}
}
queue<BoardingTicket> merge(queue<BoardingTicket> &businessTravelers, queue<BoardingTicket> &economyTravelers) {
//TODO: implementation
queue<BoardingTicket> merged;
while (economyTravelers.empty() == false) {
BoardingTicket first = economyTravelers.front();
merged.push(first);
economyTravelers.pop();
}
while (businessTravelers.empty() == false) {
BoardingTicket first = businessTravelers.front();
merged.push(first);
businessTravelers.pop();
}
return merged; //HACK: dummy return
return queue<BoardingTicket>(); //HACK: dummy return
}
queue<BoardingTicket> edit(queue<BoardingTicket> &waitingQueue) {
queue<BoardingTicket> businessTravelers;
queue<BoardingTicket> economyTravelers;
split(waitingQueue, businessTravelers, economyTravelers);
return merge(businessTravelers, economyTravelers);
}
void opravilaPriLetu(queue<BoardingTicket> readyPassengers,
queue<Luggage> appliedLuggage,
Plane lt) {
if (boardingPeople.size() != 0)
izbrisiVrsto(boardingPeople);
if (unloadedLuggage.size() != 0)
izbrisiVrsto(unloadedLuggage);
boardingPeople = edit(readyPassengers);
lt.loadLuggage(appliedLuggage);
//flying to destination
unloadedLuggage = lt.unloadLuggage();
}
};
bool MergeExclusivelyInBusinessClass() {
queue<BoardingTicket> business;
int luggageID = 0;
Traveler pt1("Victor", "Candice", 25, "1111111111111");
TravelClass pr1 = BUSINESS;
Luggage k1(luggageID++);
BoardingTicket kzv1(pt1, pr1, k1);
business.push(kzv1);
Traveler pt2("Charles", "Sennet", 17, "1111111111112");
TravelClass pr2 = BUSINESS;
Luggage k2(luggageID++);
BoardingTicket kzv2(pt2, pr2, k2);
business.push(kzv2);
Traveler pt3("Marc", "Cooper", 18, "1111111111113");
TravelClass pr3 = BUSINESS;
Luggage k3(luggageID++);
BoardingTicket kzv3(pt3, pr3, k3);
business.push(kzv3);
Traveler pt4("Frank", "McLorre", 45, "1111111111114");
TravelClass pr4 = BUSINESS;
Luggage k4(luggageID++);
BoardingTicket kzv4(pt4, pr4, k4);
business.push(kzv4);
queue<BoardingTicket> economy;
queue<BoardingTicket> mergeExpected = business;
Airline ld;
queue<BoardingTicket> actuallyMerged = ld.merge(business, economy);
if (mergeExpected.size() != actuallyMerged.size()) {
cout << "Metoda merge() did not fulfill did not fullfill with correct number of passenger ("
<< (int) mergeExpected.size() << "), but with " << (int) actuallyMerged.size() << " travelers." << endl;
return false;
}
while (!mergeExpected.empty() && !actuallyMerged.empty()) {
BoardingTicket actual = actuallyMerged.front();
actuallyMerged.pop();
BoardingTicket expected = mergeExpected.front();
mergeExpected.pop();
Traveler expectedP = expected.getTraveler();
Traveler actualP = actual.getTraveler();
TravelClass expectedPR = expected.getTravelClass();
TravelClass actualyPR = actual.getTravelClass();
Luggage expectedK = expected.getLuggage();
Luggage actualyK = actual.getLuggage();
if (expectedP.getEmso() != actualP.getEmso() || expectedP.getAge() != actualP.getAge() ||
expectedP.getSurname() !=
actualP.getSurname() ||
expectedP.getName() !=
actualP.getName() || expectedPR != actualyPR ||
expectedK.getLuggageID() !=
actualyK.getLuggageID()) {
cout << "Metoda merge() did not fill up expected queue of merged travelers with travelers that were given."
<< endl;
return false;
}
}
return true;
}
int main(int argn, char **args) {
if (MergeExclusivelyInBusinessClass())
cout << "Method merge() is successful." << endl;
else
cout << "Method merge() failed." << endl;
return 0;
}
I have troubles comprehending an error, and I'm not really sure how to solve it. Any ideas?
EDIT 1
I have been notified that error could be caused by for loop itself, because queue/stack size is constantly changing, therefore it is recommended to use while loop instead.
EDIT 2
I have finally managed to discover where exactly the problems appear:
Errors_Image
Without any further information about the error, its probable the invalid pointer error is occurring in the for-loop of the loadLuggage function. The first line of the for-loop accesses the front element of the luggages queue without checking if the queue is empty. Therefore, if the variable "maxNumberOfLuggage" has been set to a value that is greater than the size of the queue, you will get an invalid pointer error. Try modifying the for-loop to:
for (int i = 0; i < this->maxNumberOfLuggage; i++) {
Luggage luggage = luggages.front();
pallet.push(luggage);
luggages.pop();
if(luggages.empty()) break; //add this line of code
}
This may solve your problem.
If not, please provide more information on the error.
I'm doing a phone registry and in it you need to be able to add, remove and show the phones on stock. I've made it possible to add in phones but whenever I add let's say 3 phones and remove the second one then both the third and second phone are deleted and I don't understand why.
This is my CellPhoneHandler.h file:
#ifndef CELLPHONEHANDLER_H
#define CELLPHONEHANDLER_H
#include "CellPhone.h"
class CellPhoneHandler
{
private:
CellPhone **phone;
int nrOfPhones;
int priceOfPhone;
int stockCapacity;
int nrOfPhonesInArr;
public:
CellPhoneHandler();
~CellPhoneHandler();
void addPhone(string brand, int nrOf, int price);
bool removePhoneFromStock(string name, int nrOf);
int getNrOfPhones() const;
int getNrOfPhonesInArr() const;
int getPrice() const;
void getPhonesAsString(string arr[], int nrOf, int priceOfPhone) const;
};
#endif // !CELLPHONEHANDLER_H
this is my CellPhoneHandler.cpp file.
#include "CellPhoneHandler.h"
CellPhoneHandler::CellPhoneHandler()
{
this->phone = nullptr;
this->nrOfPhones = 0;
this->priceOfPhone = 0;
this->stockCapacity = 0;
this->nrOfPhonesInArr = 0;
}
CellPhoneHandler::~CellPhoneHandler()
{
for (int i = 0; i < nrOfPhonesInArr; i++)
{
delete phone[i];
}
delete[] phone;
}
void CellPhoneHandler::addPhone(string brand, int nrOf, int price)
{
if (stockCapacity < nrOfPhonesInArr + 1)
{
CellPhone ** tempArray = new CellPhone*[this->nrOfPhonesInArr + 1];
for (int i = 0; i < nrOfPhonesInArr; i++)
{
tempArray[i] = this->phone[i];
}
delete[] this->phone;
this->phone = tempArray;
this->phone[this->nrOfPhonesInArr] = new CellPhone(brand, nrOf, price);
this->nrOfPhonesInArr++;
//this->stockCapacity++;
}
}
bool CellPhoneHandler::removePhoneFromStock(string name, int nrOf)
{
bool phoneFound = false;
int index = nrOfPhonesInArr;
for (int i = 0; i < nrOfPhonesInArr; i++)
{
if (this->phone[i]->getBrand() == name);
{
index = i;
phoneFound = true;
this->nrOfPhonesInArr--;
}
}
if (phoneFound == true)
{
delete phone[index];
phone[index] = nullptr;
}
return phoneFound;
}
int CellPhoneHandler::getNrOfPhones() const
{
return this->nrOfPhones;
}
int CellPhoneHandler::getNrOfPhonesInArr() const
{
return this->nrOfPhonesInArr;
}
int CellPhoneHandler::getPrice() const
{
return this->priceOfPhone;
}
void CellPhoneHandler::getPhonesAsString(string arr[], int nrOf, int priceOfPhone) const
{
for (int i = 0; i < nrOf; i++)
{
arr[i] = this->phone[i]->toString();
}
}
The problem is caused by an unwanted ;.
if (this->phone[i]->getBrand() == name); // if ends here.
The next block is executed for all items.
{
index = i;
phoneFound = true;
this->nrOfPhonesInArr--;
}
Remove that ; in the if line.
this my Library.h file, before the Library used to do All the dirty work: in term of manipulating the arrays and stuff, but now I am trying to make the Library the middle man that just invoke the call that has to do with any array manipulations. My problem is I am trying to have one instance of Patron array, that would hold all the patrons in the Library.
#ifndef LIBRARY_H
#define LIBRARY_H
#include <string>
#include "types.h"
#include "Book.h"
#include "Patron.h"
#include "PatronArray.h"
//class PatronArray
class Library
{
public:
Library();
~Library();
void init();
int addBook(Book*);
int addPatron(Patron*);
int remPatron(int);
int findBook(int, Book**, int*);
int findPatron(string, string, Patron**, int*);
int getMaxCollIndex();
int getMaxPatronsIndex();
Book* getBook(int);
Patron* getPatron(int);
private:
Book* collection[MAX_COLL_SIZE];
PatronArray* patrons;
int maxCollIndex;
int maxPatronsIndex;
};
#endif
This is my Library.cc file
#include "Library.h"
Library::Library()
: maxCollIndex(0)
{
patrons = new PatronArray;
for (int i=0; i<MAX_COLL_SIZE; ++i) {
collection[i] = 0;
}
}
Library::~Library()
{
delete patrons;
for (int i=0; i<maxCollIndex; ++i)
delete collection[i];
}
int Library::getMaxCollIndex() { return maxCollIndex; }
int Library::getMaxPatronsIndex()
{
return patrons->getMaxPatronsIndex();
}
Book* Library::getBook(int index)
{
if (index < 0 || index >= maxCollIndex)
return 0;
return collection[index];
}
Patron* Library::getPatron(int index)
{
return patrons->getPatron(index);
}
void Library::init()
{
Book* newBook;
Patron* newPatron;
newBook = new Book("Ender's Game", "Orson Scott Card", 1985);
addBook(newBook);
newBook = new Book("Dune", "Frank Herbert", 1965);
newBook->setStatus(LOST);
addBook(newBook);
newBook = new Book("Foundation", "Isaac Asimov", 1951);
addBook(newBook);
newBook = new Book("Hitch Hiker's Guide to the Galaxy", "Douglas Adams", 1979);
addBook(newBook);
newPatron = new Patron("Jack", "Shephard");
addPatron(newPatron);
}
int Library::addBook(Book* book)
{
if (maxCollIndex >= MAX_COLL_SIZE - 1) {
return C_NOK;
}
collection[maxCollIndex++] = book;
return C_OK;
}
int Library::addPatron(Patron* patron)
{
// the lbrary is the middle ma that invokesthe calls
//return patronArray->addPatron(patron);
return patrons->addPatron(patron);
}
int Library::remPatron(int index)
{
return patrons->remPatron(index);
}
int Library::findPatron(string fn, string ln, Patron** patron, int* index)
{
return patrons->findPatron(fn,ln,patron,index);
}
int Library::findBook(int id, Book** book, int* index)
{
for (int i=0; i<maxCollIndex; ++i) {
if (collection[i] == 0)
continue;
if (collection[i]->getId() == id) {
*book = collection[i];
*index = i;
return C_OK;
}
}
*book = 0;
*index = -1;
return C_NOK;
}
This is my PatronArray.h that holds all the Patrons registered within the Library.
#ifndef PATRONARRAY_H
#define PATRONARRAY_H
#include "Patron.h"
#include "Book.h"
#include "types.h"
//class Patron;
class PatronArray
{
public:
PatronArray();
~PatronArray();
int addPatron(Patron*);
int remPatron(int);
int findPatron(string, string, Patron**, int*);
int getMaxPatronsIndex();
Patron* getPatron(int);
private:
Patron* patrons[MAX_COLL_SIZE];
int maxPatronsIndex;
};
#endif
and this is the PatronArray.cc file and please, I know there is better way of doing this by doing templating which I currently dont understand yet plus this way helps me understand the whole object oriented style.
#include<iostream>
#include<string>
#include "PatronArray.h"
/*
* Default constructor: recheck this later
*/
PatronArray::PatronArray()
:maxPatronsIndex(0)
{
for (int i = 0; i < MAX_COLL_SIZE; ++i) {
patrons[i] = 0;
}
}
/*
* Destructor: recheck this later
*/
PatronArray::~PatronArray()
{
for (int i = 0; i < maxPatronsIndex; ++i)
delete patrons[i];
}
//get the maxindex
int PatronArray::getMaxPatronsIndex() { return maxPatronsIndex; }
/*
* Adds the given Patron to the given patrons Array
*/
int PatronArray::addPatron(Patron* patron)
{
if (maxPatronsIndex >= MAX_COLL_SIZE - 1) {
return C_NOK;
}
patrons[maxPatronsIndex++] = patron;
return C_OK;
}
/*
* Used for removing a patron in the patrons array
*/
int PatronArray::remPatron(int index)
{
if (index < 0 || index >= maxPatronsIndex)
return C_NOK;
delete patrons[index];
patrons[index] = 0;
return C_OK;
}
/*
* Searches for the patron; if found, sets the contents of the second
* parameter to that patron pointer, sets the contents of the third parameter to
* its index in the collection, and returns C_OK; if not found, sets the
* contents of the second parameter to zero, the theird to -1, and returns C_NOK
*/
int PatronArray::findPatron( string fn, string ln, Patron** patron, int* index)
{
for (int i = 0; i < maxPatronsIndex; ++i) {
if (patrons[i] == 0)
continue;
if (patrons[i]->getFname() == fn && patrons[i]->getLname() == ln) {
*patron = patrons[i];
*index = i;
return C_OK;
}
}
*patron = 0;
*index = -1;
return C_NOK;
}
Patron* PatronArray::getPatron(int index)
{
if (index < 0 || index >= maxPatronsIndex)
return 0;
return patrons[index];
}
I forgot to link my PatronArray.cc to Library.cc in my makefile, thank you Jack!
for (int i = peekIndex; i < pdp->size(); i++)
{
string x = pdp->peek();
if (x.at(0) == 's')
{
out << pdp->peek() << endl;
pdp->moveForward();
}
else
{
pdp->moveForward();
}
}
The error I get is
terminate called after throwing and instance of std::out_of_range
what(): basic_string::at()
Abort
The peek method returns a string in the position of the peekIndex.
The moveFowrard method increments the peekIndex.
pdp is a vector of size 100. I am supposed to peek and print only words that start with 's' that have been pushed to the <vector>. I am basically done but this part is proving somewhat difficult.
Thanks
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class StringDeque {
protected:
vector<string>* elements;
int frontItem; //CLASS INV: indexes item with least index
int rearSpace; //CLASS INV: indexes space after item with greatest index
int upperBound; //For array[0..n-1] this is "n" not "n-1".
public:
StringDeque(int guaranteedCapacity):
elements (new vector<string>( 2*guaranteedCapacity))
frontItem (guaranteedCapacity),
rearSpace ( guaranteedCapacity),
upperBound ( 2*guaranteedCapacity)
{}
proteted:
virtual bool isEmpty() const { return frontItem == rearSpace; }
virtual bool isFull() const { return rearSpace == upperBound || frontItem == 0; }
virtual int size() const { return rearSpace - frontItem; }
virtual string popRear() {
if (isEmpty()) {
cerr<< "Later we'll define and throw an EmptyQException"<< endl;
return "";
} else {
return elements->at(--rearSpace);
}
}
virtual string popFront() {
if (isEmpty()) {
cerr<<"Later we'll define and throw an EmptyQException"<<endl;
return "";
} else {
return elements->at(frontItem++);
}
}
/** Directions include similarly testing for "full" in the C++ code.
*/
virtual void pushFront(string newItem) {
elements->at(--frontItem)= newItem;
}
virtual void pushRear(string newItem) {
elements->at(rearSpace++) = newItem;
}
virtual string toString() {
string out = "";
for (int i = frontItem; i < rearSpace; i++) {
out += elements->at(i) + " ";
}
return out;
}
};
class PeekDeque : public StringDeque {
private:
int peekIndex;
public:
PeekDeque(int guaranteedCapacity):
StringDeque(guaranteedCapacity),
peekIndex(guaranteedCapacity/2)
{}
virtual void moveFrontward() {
if (peekIndex == upperBound) {
cerr<<"Cannot move past total capacity"<<endl;
} else{
elements->at(peekIndex ++);
}
}
virtual void moveRearward () {
if (peekIndex == -1) {
cerr<<"Cannot move below total capacity"<<endl;
} else{
elements ->at( peekIndex--);
}
}
virtual string popFront() {
cerr<<"Attempt to pop from empty PeekDeque"<<endl;
}
virtual string popRear() {
cerr<<"Attempt to pop from empty PeekDeque"<<endl;
}
virtual string peek() {
if (isEmpty()) {
cerr<<"Cannot peek an Empty index"<<endl;
return "";
} else {
return elements->at(peekIndex + 1);
}
}
virtual string toString() {
string out = "";
for (int i = frontItem; i < rearSpace; i++) {
out += elements->at(i) + " ";
}
return out;
}
};
int main(){
PeekDeque* pdp = new PeekDeque(101);
pdp->pushFront("oh");
pdp->pushFront("say");
pdp->pushFront("can");
pdp->pushFront("you");
pdp->pushFront("see");
pdp->pushRear("any");
pdp->pushRear("bad bugs");
pdp->pushRear("on");
pdp->pushRear("me?");
for(int i = peekIndex; i<pdp->size(); i++){
string x =
if(x.at(0)=='s'){
cout<<pdp->peek()<<endl;
pdp->moveForward(); }
else{
pdp->moveForward();
}
}
}
May be your test should be:
if(!x.empty() && x.at(0)=='s')
I can't tell exactly, without seeing more context, but I'm pretty sure x.empty() is a probable case.
UPDATE:
pdp is a vector of size 100
Are you sure to have used the pdp.resize(100,std::string()); method to ensure all positions are initialized correctly?
it is not empty i have pushed 8 things to pdp
Also std::vector<>::resize() and std::vector<>::push_back() might not work together as you expect. Use either std::vector<>::push_back() or std::vector<>::resize() to give it a pre-allocated size and manipulate entries by index. Always check for std::vector<>::size() for indexed access.
UPDATE 2:
But the real answer is apparently simpler. You have:
virtual string peek() {
if (isEmpty()) {
cerr<<"Cannot peek an Empty index"<<endl;
return ""; // This will certainly result in a string that is empty!
Here's how your container looks like after initial pushes:
0 202
| ... | ... | ... | ... |
^ ^ ^
| | rearSpace
| peekIndex
frontItem
Now, size() returns rearSpace - frontItem, but iteration starts from peekIndex and thus goes beyond rearSpace index, peeking uninitialized (empty) strings.
That's certainly an approximate answer, since your work with indices is a mess. Please be really careful and think it through.