My program is to print the queue of information from a file but i have problem with my following code. When i run the program it keep loop. I cant figure out the problem. Any help?
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <queue>
#include <list>
using namespace std;
void simulation(ifstream &infile);
void processArrival(int *newEvent, ifstream &inFile, list<int> eventList,queue<int> printQueue);
void processDeparture(int *newEvent, list<int> eventList,queue<int> printQueue);
string name[100];
int timeAccepted[100];
int fileSize[100];
int i = 1;
int j = 1;
int currentTime;
bool checker = true;
int main(void)
{
ifstream inFile;
string fileName;
int i = 0;
inFile.open("123.txt", ios::in);
simulation(inFile);
/*while(inFile.peek() != EOF )
{
inFile>>name[i]>>timeAccepted[i]>>fileSize[i];
i++;
}
for(int s = 0; s < i; s++)
{
cout << name[s] << timeAccepted[s] << fileSize[s] <<endl;
}*/
return 0;
}
void simulation(ifstream &inFile)
{
queue<int> printQueue;
list<int> eventList;
int *newEvent;
while(inFile.peek() != '\n')
{
inFile>>name[0]>>timeAccepted[0]>>fileSize[0];
}
eventList.push_front(timeAccepted[0]);
int checkEmpty = eventList.empty();
newEvent = &eventList.front();
while(checkEmpty ==0)
{
newEvent = &eventList.front();
if(checker)
{
processArrival(newEvent, inFile, eventList, printQueue);
}
else
{
processDeparture(newEvent, eventList, printQueue);
}
checkEmpty = eventList.empty();
}
}
void processArrival(int *newEvent, ifstream &inFile, list<int> eventList,queue<int> printQueue)
{
int atFront=0;
atFront = printQueue.empty();
cout << atFront <<endl;
printQueue.push(*newEvent);
cout << printQueue.front() <<endl;
eventList.remove(*newEvent);
int temp;
if(atFront==1)
{
currentTime = *newEvent + fileSize[0];
cout << name[0] << " ## " << *newEvent << " ## " << currentTime << endl;
eventList.push_back(currentTime);
}
checker = false;
if(inFile.peek() != EOF )
{
inFile>>name[i]>>timeAccepted[i]>>fileSize[i];
eventList.push_back( timeAccepted[i] );
i++;
checker = false;
if(eventList.back() <= eventList.front())
{
temp = eventList.back();
eventList.back() = eventList.front();
eventList.front() = temp;
checker = true;
}
}
}
void processDeparture(int *newEvent, list<int> eventList,queue<int> printQueue)
{
printQueue.pop();
eventList.pop_front();
int checkEmpty = 1;
checkEmpty = printQueue.empty();
int temp;
if(checkEmpty ==0)
{
currentTime = *newEvent + fileSize[j];
cout << name[j] << " " << *newEvent << " " << currentTime << endl;
eventList.push_back(currentTime);
checker = true;
if(eventList.back() < eventList.front())
{
temp = eventList.back();
eventList.back() = eventList.front();
eventList.front() = temp;
checker = false;
}
j++;
}
}
Your processArrival and processDeparture functions are taking their eventList and printQueue arguments by value. This means that when you call them, for example in this line:
processArrival(newEvent, inFile, eventList, printQueue);
Copies of eventList and printQueue are made and passed into the processArrival function. The processArrival function then operates on those copies, and the original data is never modified. In particular, this means that the original eventList will never have any items removed from it, so it will never be empty -- it will just keep trying to process the first event over and over again.
The solution is to pass these parameters by reference. i.e. change the definition of processArrival to
void processArrival(int *newEvent, ifstream &inFile, list<int>& eventList, queue<int>& printQueue)
Note the & characters that I have inserted before eventList and printQueue. These cause references to the original data, rather than copies of the original data, to be passed into the processArival function. This means that processArrival will operate directly on the original data as you intend it to. Don't forget to make the corresponding change to processDeparture as well.
Related
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.
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;
}
I'm having trouble working with strings (char*) in structs. I can't seem to call the right data I want too.
Under processFile it shows the struct member correctly; under main it does not.
Here is my code:
#include <iostream>
#include <io.h>
#include <string>
#include "dirent.h"
#include "Stream.h"
#include "Compression.h"
#include "Definitions.h"
using namespace std;
using namespace System::IO;
using namespace System::Funcs;
bool isRawfile(char* ext);
void ProcessDirectory(string directory);
void ProcessFile(char* file);
void ProcessEntity(struct dirent* entity);
typedef struct
{
char *name;
int usize;
int csize;
BYTE *data;
} rawfile;
string path = "";
string source;
int numrawfiles = 0, numstringtables = 0;
rawfile *rawfiles = new rawfile[0x400];
FILE * zone = fopen( "C:\\Users\\jake\\Desktop\\patch_mp.zone" , "wb" );
int main(int argc, char **args)
{
if(args[1] != NULL)
{
source = string(args[1]) + "\\"; //maybe move under else here..
if(strchr(args[1], '.') != NULL)
{
cout<<"Unable to compile files, please drag a folder to compile."<<endl;
cin.get();
return 0;
}
else
{
int header[] = {1,0,0x3B4,0,0,0,1,0,0x1000,0,0,0,-1};
for(int i=0; i<13; i++)
fwrite(Converter::Int32ToBytes(header[i]), 1 , 4 , zone );
ProcessDirectory(args[1]);
for(int i=0; i<numrawfiles; i++)
cout<<"Name: "<<rawfiles[i].name<<" Length: "<< rawfiles[i].usize << " - in main()"<<endl;
fclose(zone);
}
}
else
{
cout<<"No folder selected to compile. Press any Key to quit."<<endl;
cin.get();
return 0;
}
cin.get();
return 0;
}
void ProcessDirectory(string directory)
{
string dirToOpen = path + directory;
auto dir = opendir(dirToOpen.c_str());
path = dirToOpen + "\\";
if(NULL == dir)
{
cout << "could not open directory: " << dirToOpen.c_str() << endl;
return;
}
auto entity = readdir(dir);
while(entity != NULL)
{
ProcessEntity(entity);
entity = readdir(dir);
}
path.resize(path.length() - 1 - directory.length());
closedir(dir);
}
void ProcessEntity(struct dirent* entity)
{
if(entity->d_type == DT_DIR)
{
if(entity->d_name[0] == '.')
return;
ProcessDirectory(string(entity->d_name));
return;
}
if(entity->d_type == DT_REG)
{
string fullpath = path + entity->d_name;
ProcessFile(const_cast<char *>(fullpath.c_str()));
return;
}
cout << "Not a file or directory: " << entity->d_name << endl;
}
void ProcessFile(char* file)
{
char* extension = strrchr(file, '.');
if(isRawfile(extension))
{
rawfile raw;
raw.name = (char *)&file[source.length()];
raw.usize = File::getFileSize(file);
rawfiles[numrawfiles] = raw;
cout<<"Name: "<<rawfiles[numrawfiles].name<<" Length: "<< raw.usize << " - in ProcessFile()"<<endl;
fwrite(Converter::Int32ToBytes(0x23),1,4,zone);
fwrite(Converter::Int32ToBytes(-1),1,4,zone);
numrawfiles++;
}
}
bool isRawfile(char* ext)
{
char *exts[11] = {".gsc",".cfg",".txt",".news",".png",".vision",".rmb",".script",".arena",".atr",".csc"};
for(int i=0; i<10; i++)
if(strncmp(ext,exts[i],strlen(exts[i]))==0)
return true;
return false;
}
Here is an example picture:
What am I doing wrong?
Save yourself a lot of trouble by using an std::string:
#include <string>
struct thing
{
std::string name;
int age;
};
You can also avoid the dynamically allocated array:
#include <vector>
std::vector<thing> things(3);
You are outputting the memory address of "Ben" instead of the actual String. You should use
cout << things[1]->name << endl;
which is syntactic sugar for
cout << (*things[1]).name << endl;
To add to what scd said, you are not successfully dereferencing the name member. When you try and operate on things[1].name you are operating on a pointer, which is simply a memory location.
This is one of the trickiest things when learning to use pointers. Here is some more reading on the dereference operator, and syntax hints.
http://en.wikipedia.org/wiki/Dereference_operator#Other_syntax
Edit:
After compiling myself, I realized that I was on the wrong track with this one, and that std::cout will correctly handle the char pointer. You should be able to solve this with your code, just ensure that you give your struct array a size.
This worked for me:
#include <iostream>
#define MAXSIZE 3
typedef struct
{
char* name;
int age;
}Thing;
Thing *things = new Thing[MAXSIZE];
int _tmain(int argc, _TCHAR* argv[])
{
char* names[MAXSIZE] = { "Alice", "Ben", "Carlos" };
int ages[MAXSIZE] = { 24, 25, 26 };
for(int i=0; i<MAXSIZE; i++)
{
things[i].name = names[i];
things[i].age = ages[i];
}
std::cout << things[1].name << std::endl;
return 0;
}
I have included both my definition of the Question class and its implementation, the first is a header file and the second a cpp file.
I put comments in to show where the problem is. For some reason under the constructor I can cout the questionText just fine but when I try to do this under the getQuestionText function it just outputs an empty string? Any help would be most appreciated!! Thanks!
#include <string>
#include <vector>
#include <iostream>
using namespace std;
#ifndef QUESTION_H
#define QUESTION_H
class Question{
public:
Question(int thePointValue, int theChapterNumber, \
string theQuestionText);
int getPointValue() const;
int getChapterNumber() const;
string getQuestionText() const;
virtual void writeQuestion(ostream& outfile) const;
virtual void writeKey(ostream& outfile) const;
private:
int pointValue;
int chapterNumber;
string questionText;
void writePointValue(ostream& outfile) const;
};
#endif
#include "Question.h"
Question::Question(int thePointValue, int theChapterNumber, \
string theQuestionText)
{
pointValue = thePointValue;
chapterNumber = theChapterNumber;
questionText = theQuestionText;
//HERE THIS WORKS PERFECTLY
cout << questionText << endl;
}
int Question::getPointValue() const
{
return pointValue;
}
int Question::getChapterNumber() const
{
return chapterNumber;
}
string Question::getQuestionText() const
{
//THIS IS THE PROBLEM. HERE IT OUPUTS AN EMPTY STRING NO MATTER WHAT!
cout << questionText << endl;
return questionText;
}
void Question::writeQuestion(ostream& outfile) const
{
writePointValue(outfile);
outfile << questionText << endl;
}
void Question::writeKey(ostream& outfile) const
{
writePointValue(outfile);
outfile << endl;
}
void Question::writePointValue(ostream& outfile) const
{
string pt_noun;
if (pointValue == 1)
pt_noun = "point";
else
pt_noun = "points";
outfile << "(" << pointValue << " " << pt_noun << ") ";
}
vector<Question *> QuestionsList(string filename, int min, int max)
{
vector<Question *> QuestionList;
string line;
vector<string> text;
ifstream in_file;
in_file.open(filename.c_str());
while (getline(in_file, line))
{
text.push_back(line);
}
string type;
for(int i = 0; i < text.size(); i ++)
{
int num = text[i].find('#');
type = text[i].substr(0, num);
if (type == "multiple")
{
MultipleChoiceQuestion myq = matchup(text[i]);
MultipleChoiceQuestion* myptr = &myq;
if (myq.getChapterNumber() >= min && myq.getChapterNumber() <= max)
{
QuestionList.push_back(myptr);
}
}
if (type == "short")
{
ShortAnswerQuestion myq = SAmatchup(text[i]);
ShortAnswerQuestion* myptr = &myq;
if (myq.getChapterNumber() >= min && myq.getChapterNumber() <= max)
{
QuestionList.push_back(myptr);
}
}
if (type == "long")
{
LongAnswerQuestion myq = LAmatchup(text[i]);
LongAnswerQuestion* myptr = &myq;
if (myq.getChapterNumber() >= min && myq.getChapterNumber() <= max)
{
QuestionList.push_back(myptr);
}
}
if (type == "code")
{
CodeQuestion myq = CODEmatchup(text[i]);
CodeQuestion* myptr = &myq;
if (myq.getChapterNumber() >= min && myq.getChapterNumber() <= max)
{
QuestionList.push_back(myptr);
}
}
cout << QuestionList[QuestionList.size()-1]->getQuestionText() << endl;
}
for (int i = 0; i < QuestionList.size(); i ++)
{
int numm = QuestionList.size();
cout << QuestionList[numm-1]->getQuestionText() << endl;
}
return QuestionList;
}
then when i call this in main the code breaks
vector<Question *> list = QuestionsList(pool_filename, min_chapter, max_chapter);
cout << list[0]->getQuestionText() << endl;
You are declaring, multiple times in your code, local objects and storing their pointer into the QuestionList vector (returned by the function) which, at the end of the function block, will contains dangling pointers.
MultipleChoiceQuestion myq = matchup(text[i]); // < local object
MultipleChoiceQuestion* myptr = &myq; // < pointer to local object
QuestionList.push_back(myptr); // < push back into vector
At this point you can either use dynamic memory allocation (I suggest you not to do that unless you are absolutely forced, and even in that case use one of the smart pointers provided by the standard library) or store the objects directly inside the vector.
We're supposed to implement a program to check whether the braces, brackets and parens in a given expression all match using a stack structure in C++ for my CS class. Unfortunately, I'm kinda stuck on this one, since I keeps telling me something doesn't match, even when it most decidedly does.
Here's what I got so far:
#include <stdlib.h>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
struct cell {int value; cell* next; };
cell* top;
int numElem;
void init()
{
top = NULL;
numElem = 0;
}
int pop()
{
int res;
if (top != NULL)
{
res = top -> value;
top = top -> next;
numElem--;
} else {
cout << "FAIL: Stack empty!\n";
res = -1;
}
return res;
}
void push(int element)
{
cell* cat = new cell;
cat -> value = element;
cat -> next = top;
top = cat;
}
void match(char expr[])
{
bool pass = true;
char expected;
char encountered;
char closing;
for (int i=0; pass && (i<strlen(expr)); i++)
{
if ((i==40)||(i==91)||(i==123))
push(i);
else
{
if (i==41)
expected = 40;
if (i==93)
expected = 91;
if (i==125)
expected = 123;
encountered = pop();
if (expected != encountered)
closing = i;
pass = false;
}
}
if (pass)
cout << "Parentheses match OK!\n";
else
cout << encountered << " has opened, but closing " << closing;
cout << " encountered!\nParentheses do not match\n";
}
int main(int argc, char * argv[])
{
init();
match(argv[1]);
return 0;
}
Since the stack framework existed from a previous exercise and worked fine there, I'm strongly assuming whatever error there is should be in void match
else
cout << encountered << " has opened, but closing " << closing;
cout << " encountered!\nParentheses do not match\n";
The second line always prints. It should be
else
{
cout << encountered << " has opened, but closing " << closing;
cout << " encountered!\nParentheses do not match\n";
}
Also
if (expected != encountered)
closing = i;
pass = false;
should also be
if (expected != encountered)
{
closing = i;
pass = false;
}
Do you come from python? Indentation doesn't affect logic in C++, it just affects readability.
In your match function you should test characters, not their indices:
void match(char expr[])
{
...
for (int i=0; pass && (i<strlen(expr)); i++)
{
char c = expr[i]; // use this c instead of i below!!!!!!!
if ((c==40)||(c==91)||(c==123))
push(c);
else
{
if (c==41)
expected = 40;
if (c==93)
expected = 91;
if (c==125)
...
Also you did not update counter in your push:
void push(int element)
{
...
++numElems; // Was missing!!!!
}