Calling two Queue class function in a loop - c++

I have problem with this code of mine. Whenever i call two function of the class, and in those class, there is if-else statement, and print the output on screen, it will only run the if clause of the two functions and not the else. How can i fix this?
For example:
This is my Queue.h file:
#ifndef QUEUE_H
#define QUEUE_H
class Queue {
private:
//private variables
int arr_size;
char *arr;
int head;
int tail;
int count;
public:
Queue(int); //constructor
//functions
int enqueue(char);
int dequeue(char&);
};
#endif
This is my Queue.cpp file:
#include <iostream>
#include "Queue.h"
using namespace std;
Queue::Queue(int size) {
//initializing
arr_size = size;
arr = new char[size];
for (int i = 0; i < arr_size; i++) {
arr[i] = NULL;
}
head = 0;
tail = 0;
count = 0;
}
int Queue::enqueue(char value) {
if (count<arr_size) //if array is not full, execute below
{
arr[tail++] = value; //pass value of first-to-last element in array
count++; //counting the input value
cout << "\nEnqueue Value: "<< arr[tail-1];
return 0;
}
else {
tail = 0;
cout << "\nArray is full. Value cannot be write: " << value;
return -1;
}
}
int Queue::dequeue(char &read_val) {
if (count !=0) { //if array has elements, execute below
read_val = arr[head]; //pass-by-reference the value of first-to-last element in array to parameter of function
cout <<"\nDequeue Value: "<<read_val;
arr[head] = NULL;
count--;
if (head++ == arr_size) {
head = 0;
}
return 0;
}
else if (count ==0) {
cout << "\nArray is empty. Cannot be dequeue";
return -1;
}
}
And this is what my Source file:
#include "Queue.h"
#include <iostream>
using namespace std;
int main() {
int n;
cout << "Please enter the desired size of the array: ";
cin >> n;
char read_val = NULL;
Queue myqueue(n);
char arr[] = "Hello World, this is ELEC3150";
int size = sizeof(arr)-1;
int count = 0;
for (int i = 0; i < 5; i++) {
myqueue.enqueue(arr[count]);
count++;
myqueue.dequeue(read_val);
}
If i enter the size of the array to be less than 5, it must print the error message saying the array is full in the enqueue function and the array is empty in the dequeue function but did not.

Related

Checking if a word is a palindrome by reversing a stack without using any prewritten functions

#include <iostream>
#include <string>
using namespace std;
#define Max 100000
class Stack {
private:
int top =-1;
char letters[Max];
public:
void setTop(int t) {
top = t;
}
int getTop() {
return top;
}
bool isEmptyStack() {
if (top == -1) {
return true;
}
else{ return false;
}
}
char push(char x,int s) {
if (top != s - 1){
top++;
x = letters[top];
return x;
}
}
char pop() {
if ((isEmptyStack())==false){
cout << "the deleted value is: " << l[top]<<endl;
top--;
return l[top];
}
}
};
void reverse(char letters[], char temp[], int size, Stack stack) {
int i=0;
for (i = 0; i < size; i++) {
stack.push(letters[i],size);
}
i = 0;
cout << temp<<endl;
while (stack.isEmptyStack() == false)
{
letters[-1] = stack.getTop();
stack.pop();
stack.push(letters[i],size);
i++;
}
/* for (int i = 0; i < size; i++) {
cout << temp[i];
}*/
}
int myStringLength(const char* letter)
{
for (int i = 0, c = 0; letter[i] != '\0'; i++, c++) {
if (letter[i] != '\0')
for (; letter[i] != '\0'; i++, c++)
if (letter[i] == '\0') break;
return c;
}
}
int main()
//initializes the main function
{
Stack stack;
string w;
std::cout << "Enter a Word: ";
getline(cin,w);
char* letters = &w[0];
// sets the character text array to set the number of characters equal to the size of the string
//calls the processData function
std::cout << letters<<endl;
int size = myStringLength(letters);
reverse(letters, letters, size, stack);
return 0;//returns the function at 0.
}
I set out to create a program that will check if a word is a palindrome(meaning it is spelled the same normally and if the word is reversed.) I am not yet at that point that is just the final objective. In my code, I have created a stack class because I wanted to feel the satisfaction of getting the same result using my own code. My problem is the stack is not reversing it is returning some weird characters that I don't have the keys on my keyboard to replicate.
The desired outcome should be word's reversed characters.
if the word is food the function should be returning doof. I have already compared the reversed stack to the original and printed the final statement. I fixed the char letters[];
If you're open to using a simple function instead of a Stack then you could use the following program since it is much more simple than your Stack version and hence less-error prone.
#include <iostream>
#include <string>
bool checkIfPalindroom(const std::string &str)
{
for(int i=0;i<(str.size()/2);i++)
{
if (str[i] != str[str.size() - i - 1])
{
return false;//if this if is satisfied even once, return false
}
}
return true;//if the control flow reaches here this will mean that no if was satisfied and hence return true
}
int main()
{
std::string myString = "Somearbitrarystring";
if(checkIfPalindroom(myString))//call the function
{
std::cout<<"The given string: "<<myString <<" is a palindrome"<<std::endl;
}
else
{
std::cout<<"The given string: "<<myString<<" is not a palindrome"<<std::endl;
}
return 0;
}

(C++) terminate called after throwing an instance of 'std::bad_alloc'

I keep getting an error of bad memory allocation. I've spent the whole night trying to find where I went wrong but I can't figure out what.
I've combed through every line but still nothing. Could it be that my program/laptop just isn't strong enough?
Any help would be extremely helpful. My head is ringing and I need some rest.
Here's my code:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
// struct to store word + count combinations
struct wordItem{
string word;
int count;
};
void getStopWords(char *ignoreWordFileName, vector<string>& _vecIgnoreWords);
bool isCommonWord(string word, vector<string>& _vecIgnoreWords);
void printTopN(wordItem wordItemList[], int topN);
void doubleArray(wordItem wordItemList[], int size);
int getTotalNumberNonCommonWords(wordItem wordItemList[], int size, int wordCount);
const int STOPWORD_LIST_SIZE = 50;
// ./a.out 10 HW1-HungerGames_edit.txt HW1-ignoreWords.txt
int main(int argc, char* argv[]){
vector<string> vecIgnoreWords(STOPWORD_LIST_SIZE);
// verify we have the correct # of parameters, else throw error msg & return
if (argc != 4){
cout << "Usage: ";
cout << argv[0] << " <number of words> <filename.txt> <ignorefilename.txt>"<< endl;
return 0;
}
//Set vector with stop words
getStopWords(argv[3], vecIgnoreWords);
//initialize struct array
int aSize = 100;
wordItem *theStructArray = new wordItem[aSize];
int counter = 0;
int doubleCount = 0;
//read main txt file
ifstream inFile(argv[1]);
if(inFile.is_open()){
string line;
string theWord;
//extract words from file
while(getline(inFile, line)){
istringstream iss(line);
//extract and analyze word
while(iss >> theWord){
if(!(isCommonWord(theWord, vecIgnoreWords))){
bool inStructArray = false;
int inStructPosition;
//search for word in Struct array
while (inStructArray == false){
for(int i=0; i<aSize; i++){
if (theWord == theStructArray[i].word){
inStructArray = true;
inStructPosition = i;
}
}
break;
}
//if word is in struct array
if (inStructArray == true){
theStructArray[inStructPosition].count++;
}
//else if it isn't
else{
//create new wordItem and add into struct
wordItem newWord;
newWord.word = theWord;
newWord.count = 1;
theStructArray[counter+(100*doubleCount)] = newWord;
counter++;
}
//if struct array hits maximum amount of elements,
if (counter == (aSize-1)){
doubleArray(theStructArray, aSize);
counter = 0;
doubleCount++;
aSize +=100;
}
}
}
}
inFile.close();
}
//Bubble sort masterArray
int bI, bJ, flag = 1;
wordItem bTemp;
for(bI=1; (bI <= aSize && flag); bI++){
flag = 0;
for(bJ=0; bJ<aSize; bJ++){
if(theStructArray[bJ+1].count > theStructArray[bJ].count){
bTemp = theStructArray[bJ];
theStructArray[bJ] = theStructArray[bJ+1];
theStructArray[bJ+1] = bTemp;
flag = 1;
}
}
}
//Print topN words
printTopN(theStructArray, atoi(argv[1]));
//print others
cout << "#" << endl;
cout << "Array doubled: " << doubleCount << endl;
cout <<"#" << endl;
cout << "Unique non-common words: "<< (aSize-100+counter)<<endl;
cout << "#"<<endl;
cout <<"Total non-common words: "<< getTotalNumberNonCommonWords(theStructArray, aSize, counter)<<endl;
return 0;
}
void getStopWords(char *ignoreWordFileName, vector<string>& _vecIgnoreWords){
ifstream inFile(ignoreWordFileName);
if(inFile.is_open()){
int a = 0;
string line;
while(getline(inFile, line)){
_vecIgnoreWords.insert(_vecIgnoreWords.begin() + a, line);
}
inFile.close();
}
return;
}
bool isCommonWord(string word, vector<string>& _vecIgnoreWords){
for(int i=0; i<STOPWORD_LIST_SIZE; i++){
if(word == _vecIgnoreWords.at(i)){
return true;
}
}
return false;
}
void printTopN(wordItem wordItemList[], int topN){
cout << endl;
for(int i=0; i<topN; i++){
cout<< wordItemList[i].count << '-' << wordItemList[i].word << endl;
}
return;
}
void doubleArray(wordItem wordItemList[], int size){
wordItem *tempArray = new wordItem[size+100];
for(int i=0; i<size; i++){
tempArray[i] = wordItemList[i];
}
delete [] wordItemList;
wordItemList = tempArray;
}
int getTotalNumberNonCommonWords(wordItem wordItemList[], int size, int wordCount){
int total = 0;
for(int i=0; i<(size-100+wordCount); i++){
total+=wordItemList[i].count;
}
return total;
}
You are doing very bad things in void doubleArray(wordItem wordItemList[], int size)
you can call delete [] on the array if you pass an array, but you cannot change its value, so doubleArray(theStructArray, aSize); will cause theStructArray to be deleted but not assigned to the memory you allocated. You are just assigning the local variable in the function doubleArray
It is similar to:
void doubleit(int x)
{
x *= 2;
}
int y=3;
doubleit(y);
here x was momentarily doubled to 6, but y never changed.
you need to use references, or better make theStructArray a std::vector and be done with it.

Why is the 98th element in my Stack implementation such a bizarre value?

I have the following stack data structure implementation in C++:
// file: Stack.h
#pragma once
#include <iostream>
#include <exception>
class CStack
{
private:
int counter;
int *data;
int currentmaxsize;
void adjust();
public:
void push(int value);
int pop();
int peek();
int getsize();
CStack();
~CStack();
};
// file: Stack.cpp
#include "Stack.h"
void CStack::adjust()
{
int *temp = new int[currentmaxsize];
for (int i = 0; i < counter; i++)
{
temp[i] = data[i];
}
delete data;
data = new int[currentmaxsize * 2];
for (int i = 0; i < counter; i++)
{
data[i] = temp[i];
}
delete temp;
currentmaxsize *= 2;
}
int CStack::getsize()
{
return counter;
}
void CStack::push(int value)
{
if (counter+1 == currentmaxsize)
{
adjust();
}
counter++;
data[counter] = value;
}
int CStack::peek()
{
return data[counter];
}
int CStack::pop()
{
if (counter > 0)
{
int ret = data[counter];
counter--;
return ret;
}
else if (counter == 0)
{
throw std::exception("cannot pop empty stack");
}
return 0xFFFFFFFF;
}
CStack::CStack()
{
data = new int[100];
currentmaxsize = 100;
counter = 0;
}
CStack::~CStack()
{
delete data;
}
This is a fairly standard stack implementation. The only thing that is different from the kind of stack you would see in most textbooks is the adjust() function, which reallocates the stack with a bigger size if the original boundary is reached.
I wrote the following driver for the data structure as well:
// file: driver.cpp
#include <iostream>
#include "Stack.h"
int main(int argc, char *argv[])
{
CStack stack;
for (int i = 0; i < 200; i++)
{
stack.push(i);
std::cout << "Pushed: " << i << std::endl;
//std::cout << "New stack size: " << stack.getsize() << std::endl;
}
int len = stack.getsize();
std::cout << "len = " << len << std::endl;
for (int i = 0; i < len; i++)
{
std::cout << "Popped: " << stack.pop() << std::endl;
//std::cout << "New stack size: " << stack.getsize() << std::endl;
}
return 0;
}
This works almost as I would expect it to, except this one value in the program output:
Popped: 100
Popped: 99
Popped: 7798895
Popped: 97
Popped: 96
It is always the value of the 98th element in the stack that has a bizarre value like this, and I don't know why it is - the adjust() function is being called when the stack hits 100 values, not 99, so I don't imagine it's a problem with the adjust function.
Your push and peek and probably other functions use counter as the index of the last element. But other parts of your code use counter as the number of elements so counter-1 would be the index of last. So data is lost during adjust
Select one design: The valid indexes are 0 through counter-1 inclusive or 0 though counter or 1 through counter (wasting position 0).
I only like the first of those choices but any one of them can work (your existing code is closest to being the third). Having different parts play by different rules doesn't work.
I see at least one bug. You are using delete after doing a new[].
new should be matched with delete and new[] should be matched with delete[]. Otherwise it's undefined behavior.
Also, you are doing unnecessary copying in your adjust function.

Building a 2D array class from a 1D array class in C++

in my C++ class we are finally getting conceptually fairly deep (well, relatively!) and I'm struggling with building a class from a previous class.
Here is my first class header, which builds partially filled array objects. To my knowledge, it is fully functional:
#ifndef PARTIALARRAY_H
#define PARTIALARRAY_H
#include <iostream>
#include <string.h>
using namespace std;
typedef int ITEM_TYPE;
ITEM_TYPE const MAX = 50;
class PartialArray
{
public:
//-----------------------------------------ctors:-----------------------------------------
PartialArray();
PartialArray(const int init[], int used);
//-----------------------------------------member functions:-----------------------------------------
void PrintArray();
int Search(ITEM_TYPE key);
int Append(ITEM_TYPE appendMe);
int ShiftRight(int shiftHere);
int ShiftLeft(int shiftHere);
int InsertBefore(ITEM_TYPE insertThis, int insertHere);
int InsertAfter(ITEM_TYPE insertThis, int insertHere);
int Delete(int deleteHere);
void DeleteRepeats();
int NumUsed();
void Sort();
void Reverse();
string ErrorDescr(int failCode);
//-----------------------------------------operators:-----------------------------------------
ITEM_TYPE& operator [] (ITEM_TYPE x);
private:
//-----------------------------------------member vars:-----------------------------------------
ITEM_TYPE a[MAX];
int numUsed;
};
#endif // PARTIALARRAY_H
And here are the class functions:
#include "partialarray.h"
#include <iostream>
#include <string.h>
using namespace std;
//-----------------------------------------ctors:-----------------------------------------
PartialArray::PartialArray()
{
numUsed=0;
}
PartialArray::PartialArray(const int init[], int used)
{
numUsed = used;
for(int i=0; i<numUsed; i++)
{
a[i]=init[i];
}
}
//-----------------------------------------member functions:-----------------------------------------
//Prints the array up to its last used element
void PartialArray::PrintArray()
{
for(int i=0; i<numUsed; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
//Searches the array for a particular value and returns the index at which the value first appears
int PartialArray::Search(ITEM_TYPE key)
{
for(int i=0; i<numUsed; i++)
{
if(a[i]==key)
return i;
}
return -1;
}
//Takes a number and appends it to the end of the array after the last interesting element
int PartialArray::Append(ITEM_TYPE appendMe)
{
if(numUsed<MAX)
a[numUsed++] = appendMe;
else
return 1;
return 0;
}
//Shifts all elements of the array to the right starting at a particular index
int PartialArray::ShiftRight(int shiftHere)
{
if(shiftHere<numUsed)
{
ITEM_TYPE save = a[numUsed-1];
for(int i=numUsed; i>=shiftHere; i--)
{
a[i] = a[i-1];
}
a[shiftHere] = save;
return 0;
}
else
return 2;
}
//Shifts all elements of the array to the left starting at a particular index
int PartialArray::ShiftLeft(int shiftHere)
{
if(shiftHere<numUsed)
{
ITEM_TYPE save = a[shiftHere];
for(int i=shiftHere; i<numUsed; i++)
{
a[i] = a[i+1];
}
a[numUsed-1] = save;
return 0;
}
else
return 2;
}
//Takes a number and a position and inserts the number before that position in the array shifting the elements to the right
int PartialArray::InsertBefore(ITEM_TYPE insertThis, int insertHere)
{
if(insertHere>numUsed)
return 2;
else
{
numUsed++;
ShiftRight(insertHere);
a[insertHere] = insertThis;
}
return 0;
}
//Takes a number and a position and inserts the number after that position in the array shifting the elements to the right
int PartialArray::InsertAfter(ITEM_TYPE insertThis, int insertHere)
{
if(insertHere>numUsed)
return 2;
else if(numUsed>=MAX)
return 1;
else
{
numUsed++;
ShiftRight(insertHere+1);
a[insertHere+1] = insertThis;
}
return 0;
}
//Takes a position and removes that item from the array, shifting all the elements to the left
int PartialArray::Delete(int deleteHere)
{
if(deleteHere <= numUsed)
{
ShiftLeft(deleteHere);
numUsed--;
return 0;
}
else
return 2;
}
//Deletes repeated elements in the array and replaces the with 0
void PartialArray::DeleteRepeats()
{
for(int i=0;i<numUsed;i++)
{
ITEM_TYPE n=a[i];
for(int j=i+1; j<numUsed;j++)
{
if(n == a[j])
{
Delete(j);
j--;
}
}
}
}
//Returns number of interesting elements in the array
int PartialArray::NumUsed()
{
return numUsed;
}
//Utilizes a bubble sort algorithm
void PartialArray::Sort()
{
bool swap = true;
int j = 0;
int save;
while (swap==true)
{
swap = false;
j++;
for (int i = 0; i < numUsed - j; i++)
{
if (a[i] > a[i + 1])
{
save = a[i];
a[i] = a[i + 1];
a[i + 1] = save;
swap = true;
}
}
}
}
void PartialArray::Reverse()
{
for(int i=0;i<numUsed-1;i++)
{
ITEM_TYPE save = a[numUsed-1];
ShiftRight(i);
a[i] = save;
}
}
//Returns the appropriate error description for a particular fail code
string PartialArray::ErrorDescr(int failCode)
{
switch(failCode)
{
case -1:
return "ERROR: item not found";
break;
case 1:
return "ERROR: array is full";
break;
case 2:
return "ERROR: unused index";
break;
default:
return "UNKNOWN ERROR";
break;
}
}
//-----------------------------------------operators:-----------------------------------------
ITEM_TYPE& PartialArray::operator [](ITEM_TYPE x)
{
return a[x];
}
Now, here is where things have gotten tricky. To build the two dimensional array class, I'm supposed to create an array of arrays. I'm at a loss as to how I should go about this, and after tinkering and googling for a few hours I've only become more confused. Specifically, the <<, [], and [](constant version) operators and the TwoDArray constructor have thrown me for a loop, and I'm stuck without much sense of what to do next. Here is the TwoD header file:
#ifndef TWODARRAY_H
#define TWODARRAY_H
#include "partialarray.h"
#include <iostream>
#include <string.h>
typedef int ITEM_TYPE;
class TwoDArray
{
friend ostream& operator << (ostream &outs, const TwoDArray& printMe);
public:
//ctors:
TwoDArray();
//member functions:
//PartialArray& operator [](int index); //[ ] operator for the TwoDArray object
//PartialArray operator [](int index) const; //[ ] operator for the TwoDArray object (const version)
int Append(int appendMe, int row);
int InsertBefore(int insertMe, int row, int column);
int InsertAfter(int insertMe, int row, int column);
int Delete(int row, int column);
bool Search(ITEM_TYPE key, int &row, int &column);
private:
//member vars:
PartialArray a[MAX];
};
#endif // TWODARRAY_H
And this is what I've tried to define thus far:
TwoDArray::TwoDArray()
{
const int array0[]= {0};
PartialArray array(array0, MAX);
}
ostream& operator << (ostream &outs, const TwoDArray& printMe)
{
for(int i=0;i<MAX;i++)
{
outs << printMe.a[i];
}
return outs;
}
Ideally, the << operator will print an m by n array of items.

Crashing when objects are deleted

It's crashing at the very end of the main() function where it needs to delete the starters objects. The error message that pops up when I run the program says: Debug assertion failed! Expression: _BLOCK_IS_VALID(pHead->nBlockUse). How do i fix it from crashing when deleting the starters objects?
#include <iostream>
#include <fstream>
#include "olympic.h"
using namespace std;
ofstream csis;
int main() {
const int lanes = 4;
Ranker rank(lanes);
csis.open("csis.txt");
// First make a list of names and lane assignments.
Competitor* starters[lanes];
starters[0] = new Competitor("EmmyLou Harris", 1);
starters[1] = new Competitor("Nanci Griffith", 2);
starters[2] = new Competitor("Bonnie Raitt", 3);
starters[3] = new Competitor("Joni Mitchell", 4);
// The race is run; now assign a time to each person.
starters[0]->setTime((float)12.0);
starters[1]->setTime((float)12.8);
starters[2]->setTime((float)11.0);
starters[3]->setTime((float)10.3);
// Put everyone into the ranker.
for (int i = 0; i < lanes; i++)
rank.addList(starters[i]);
// Now print out the list to make sure its right.
cout << "Competitors by lane are:" << endl;
csis << "Competitors by lane are:" << endl;
for (int i = 1; i <= lanes; i++)
rank.getLane(i)->print();
// Finally, show how they finished.
cout << "Rankings by finish are:" << endl;
csis << "Rankings by finish are:" << endl;
for (int i = 1; i <= lanes; i++)
rank.getFinish(i)->print();
for (int i = 0; i < lanes; i++)
delete starters[i];
csis.close();
}
ranker.cpp:
#include "ranker.h"
#include "competitor.h"
#include <stdlib.h>
Ranker::Ranker(int lanes) {
athlete = new Competitor*[lanes];
numAthletes = 0;
maxAthletes = lanes;
}
int Ranker::addList(Competitor* starter) {
if (numAthletes < maxAthletes && starter != NULL) {
athlete[numAthletes] = starter;
numAthletes++;
return numAthletes;
}
else
return 0;
}
Competitor* Ranker::getLane(int lane) {
for (int i = 0; i < numAthletes; i++) {
if (athlete[i]->getLane() == lane) {
return athlete[i];
}
}
return NULL;
}
Competitor* Ranker::getFinish(int position) {
switch(position) {
case 1:
return athlete[3];
break;
case 2:
return athlete[2];
break;
case 3:
return athlete[1];
break;
case 4:
return athlete[0];
break;
}
return NULL;
}
int Ranker::getFilled() {
return numAthletes;
}
Ranker::~Ranker() {
delete [] athlete;
}
competitor.h:
#ifndef _COMPETITOR_H
#define _COMPETITOR_H
class Competitor {
private:
char* name;
int lane;
double time;
public:
Competitor(char* inputName, int inputLane);
Competitor();
void setTime(double inputTime);
char* getName();
int Competitor::getLane();
double getTime();
void print();
~Competitor();
};
#endif
competitor.cpp:
#include "competitor.h"
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
Competitor::Competitor(char* inputName, int inputLane) {
name = inputName;
lane = inputLane;
}
Competitor::Competitor() {
name = 0;
lane = 0;
time = 0;
}
void Competitor::setTime(double inputTime) {
time = inputTime;
}
char* Competitor::getName() {
return name;
}
int Competitor::getLane() {
return lane;
}
double Competitor::getTime() {
return time;
}
void Competitor::print() {
cout << setw(20) << name << setw(20) << lane << setw(20) << setprecision(4) << time << endl;
}
Competitor::~Competitor() {
delete [] name;
}
Call stack:
before crash: http://i.imgur.com/d4sKbKV.png
after crash: http://i.imgur.com/C5cXth9.png
After you've added Competitor class, it seems the problem is that you delete its name in Competitor's destructor. But you assign it from string literal which can't really be deleted. I'm sure the stack trace leading to assertion will prove that.
One way of solving the problem would be using std::string to store the name.
Problem is when deleting the char* value on destructor, which is assigned with const char instead new char. So i have slightly changed the constructor to copy the const char to new char.
Competitor::Competitor(char* inputName, int charlen, int inputLane)
{
name = new char[charlen + 1];
memcpy(name , inputName, charlen );
name [charlen] = '\0';
lane = inputLane;
}