I'm currently working on an assignment for school that says I should create a Queue. It seems to be working. The only problem is that there is an unexpected char at the beginning of my Queue. I use class CQueue to push and pop values from the queue. It is essential that I use this class instead of something like std::queue or deque.
class CQueue
{
private:
char *bottom_;
char *top_;
int size_;
public:
CQueue(int n = 20){
bottom_ = new char[n];
top_ = bottom_;
size_ = n;
}
void push(char c){
*top_ = c;
top_++;
}
int num_items() {
return (top_ - bottom_ );
}
char pop(){
bottom_++;
return *bottom_;
}
void print(){
cout << "Queue currently holds " << num_items() << " items: " ;
for (char *element=top_; element > bottom_; element--) {
cout << " " << *element;
}
cout << "\n";
}
This is my main method:
int main(){
CQueue q(10);
q.push('s');q.push('t');q.push('a');q.push('c');q.push('k');
q.print();
cout << "Popped value is: " << q.pop() << "\n";
q.print();
q.push('!');
q.push('?');
cout << "Popped value is: " << q.pop() << "\n";
q.print();
while (!q.empty()) q.pop();
if (q.num_items() != 0) {
cout << "Error: Stack is corrupt!\n";
}
q.print();
cout << "End of program reached\n"<< endl;
return 0;
When I run this code the queue gets filled but *bottom_ is replaced with a '=' symbol. This is my output:
Queue currently holds 5 items: ═ k c a t
Popped value is: t
Queue currently holds 4 items: ═ k c a
Popped value is: a
Queue currently holds 5 items: ═ ? ! k c
Queue currently holds 0 items:
End of program reached
I've been banging my head over this one for a while now so I hope that maybe you can shed some light on this problem!
As your push() is defined, *top_ is NOT in queue. It is one element after the end of queue. Therefore, you should define your print() to iterate from top_ - 1.
Also as #stellarossa mentioned, you should return the character pointed by bottom_ before increment. That is,
char pop() { return *(bottom_++); }
char pop(){
bottom_++;
return *bottom_;
}
you're incrementing your pointer and then returning the value. it should be the other way around.
Are you using an array or linked list?
Keep it simple and use an array with a count variable.
#include <iostream>
using namespace std;
class CQueue
{
private:
char * q;
int size_;
int count;
public:
CQueue(int n = 20){
q = new char[n];
size_ = n;
count = 0;
}
void push(char c){
assert(count != size);
q[count] = c;
count++;
}
int num_items() {
return count;
}
char pop() {
assert(count != 0);
char ret = q[count-1];
count--;
return ret;
}
void print(){
cout << "Queue currently holds " << num_items() << " items: " ;
for (int i = 0; i < count; i++) {
cout << " " << q[i];
}
cout << "\n";
}
At least two bugs my friend.
1) The print() method starts printing *top which is 1 past the last member. Should be:
for (char *element=top_-1; element >= bottom_; element--) {
cout << " " << *element;
}
2) The pop() method is wrong:
should be:
char pop(){
return (top_ > bottom_) ? *top_-- : 0;
}
Related
I have a bunch of tuples (int array[N], string message) to store. I want to be able to add/delete a lot of elements from this array very quickly but, most importantly, given another array array2, I want to find every string such that for all i : array[i] <= array2[i] (not implemented yet).
Thus, I thought about using a tree of height N where a leaf is a message. If it is a leaf, it should contain a vector if it's a node, it should contain a map.
I am using an union to manage whether a tree is a leaf or a node.
My delete function should delete the leaf and all the nodes that lead only to this leaf.
I can insert a message (or multiple different messages). However, I can't reinsert a message that I previously deleted. It raises a bad_alloc error.
#include <iostream>
#include <map>
#include <vector>
using namespace std;
struct Node{
enum{LEAF, NODE} tag;
union {
std::map<int, struct Node*> map;
std::vector<std::string> msg;
};
Node(std::string m){
tag = LEAF;
cout << "Flag 1 : Crashing here, for some reasons a map is allocated" << "\n";
msg.push_back(m);
cout << "Flag 2 : Did you manage to fix it ?" << "\n";
}
Node(){
tag = NODE;
map = std::map<int, struct Node*>();
}
~Node(){
if (tag==NODE){
map.~map();
} else {
msg.~vector();
}
}
};
void insert(int* array, int size, Node* node, std::string msg){
cout << "Insert\n";
if (size > 1){
if (!node -> map.count(array[0])){
node->map[array[0]] = new Node();
}
insert(array+1, size-1, node->map[array[0]], msg);
} else {
if (!node->map.count(array[0])){
cout << "Case 1\n";
node -> map[array[0]] = new Node(msg);
}
else{
cout << "Case 2\n";
node -> map[array[0]]->msg.push_back(msg);
}
}
}
bool find(int * array, int size, Node * node){
if (!node -> map.count(array[0])){
return false;
}
if (size==1){
return true;
}
return find(array+1, size-1, node->map[array[0]]);
}
std::vector<std::string> find_vec(int * array, int size, Node * node){
if (!node -> map.count(array[0])){
return std::vector<std::string>();
}
if (size==1){
if (!node -> map.count(array[0])){
return std::vector<std::string>();
}
return node -> map[array[0]]->msg;
}
return find_vec(array+1, size-1, node->map[array[0]]);
}
void print_array(std::vector<std::string> v){
for (auto & elem : v){
cout << elem << " ";
}
cout << "\n";
}
void erase(int * array, int size, Node * node){
std::vector<Node*> vec;
int i = 0;
Node *t = node;
while (i < size){
if (t -> map.count(array[i])){
vec.push_back(t);
t = t-> map[array[i]];
} else
break;
i++;
}
if (i == size){
// Deleting the leaf
cout << "Deleting Leaf\n";
delete t;
cout << "Deleting vec [" << size-1 << "] elem " << array[size-1] << "\n";
cout << "Deleted ? " << vec[size-1]->map.erase(array[size-1]) << "\n";
// Deleting the path if it has no other leaf
cout << "Delete Path\n";
for (i = size-1; i > 0; i--){
//cout << "debut loop " << i << "\n";
//vec[i-1]->map.erase(array[i-1]);
if (!vec[i] -> map.size()){
delete vec[i];
cout << "Deleting vec [" << i-1 << "] elem " << array[i-1] << "\n";
cout << "Deleted ? " << vec[i-1]->map.erase(array[i-1]) << "\n";
}
else
break;
//cout << "fin loop\n";
}
}
}
int main()
{
Node * Tree = new Node;
for (int k = 0; k < 2; k++){
cout << "k = " << k << "\n---------------------------------------------------------------------------------------------\n";
int size = 4;
int array[4] = {0,1,2,3};
std::string m1 = "Random message that I want to store as many times as I want";
insert(array, size, Tree, m1);
cout << "find : " << find(array, size, Tree) << "\n";
std::vector<std::string> vec1 = find_vec(array, size, Tree);
cout << "vec ";
print_array(vec1);
cout << "-------------------\n";
erase(array, size, Tree);
cout << "We should find the message \n";
print_array(vec1);
cout << "-------------------\n";
cout << "We should not find the message \n";
vec1 = find_vec(array, size, Tree);
print_array(vec1);
cout << "-------------------\n";
}
return 0;
}
A union should be treated with care, especially when used with non-trivial members like in your example. Specifically of interest is this passage from cppreference:
If a union contains a non-static data member with a non-trivial
special member function (copy/move constructor, copy/move assignment,
or destructor), that function is deleted by default in the union and
needs to be defined explicitly by the programmer.
If a union contains a non-static data member with a non-trivial
default constructor, the default constructor of the union is deleted
by default unless a variant member of the union has a default member
initializer .
The map member is not constructed and therefore you cannot just start using it.
I recommend using std::variant as a safe alternative to a raw union. Your example would look like the following without a need for your enum:
struct Node {
std::variant<std::map<int, Node*>, std::vector<std::string>> data;
Node(std::string m){
data.emplace<1>();
cout << "Flag 1 : Crashing here, for some reasons a map is allocated" << "\n";
std::get<1>(data).push_back(m);
cout << "Flag 2 : Did you manage to fix it ?" << "\n";
}
// ...
};
I am getting a access violation error in my code when I try run it. The program is a priority queue that inserts a value and prints the heap after each insertion and min extract.
Header File:
#pragma once
/*
Header file for the priority queue class
*/
#ifndef PRIORITYQUEUE_H
#define PRIORITYQUEUE_H
class priorityQueue
{
private:
int size;
int *data;
public:
static const int CAPACITY = 50;
priorityQueue();//constructor
~priorityQueue();//destructor
int getParent(int index);
int getLeftChild(int index);
int getRightChild(int index);
void swap(int &, int &);
void insert(int item); //enqueue - heap_insert
void printArray(int []);
void heapify(int index);
//remove and return the smallest item currently in the priority queue
int extractMin();//dequeue
bool empty() const;
int min() const; //return the smallest item
};
#endif
Main Code:
#include <iostream>
#include "priorityQueue.h"
using namespace std;
int main()
{
priorityQueue myqueue; //class object
if (myqueue.empty())
cout << "My priority Queue is empty\n" << endl; //prompt
myqueue.insert(59); //Insert value into queue
cout << "After inserting 59 Priority Queue has" << endl;
myqueue.insert(41);
cout << "After inserting 41 Priority Queue has" << endl;
myqueue.insert(25);
cout << "After inserting 25 Priority Queue has" << endl;
myqueue.insert(12);
cout << "After inserting 12 Priority Queue has" << endl;
myqueue.insert(91);
cout << "After inserting 91 Priority Queue has" << endl;
myqueue.min();
myqueue.extractMin();
cout << "After extracting the minimum value Priority Queue has" << endl;
myqueue.insert(34);
cout << "After inserting 34 Priority Queue has" << endl;
myqueue.insert(63);
cout << "After inserting 63 Priority Queue has" << endl;
myqueue.extractMin();
cout << "After extracting the minimum value Priority Queue has" << endl;
myqueue.insert(75);
cout << "After inserting 75 Priority Queue has" << endl;
myqueue.insert(85);
cout << "After inserting 85 Priority Queue has" << endl;
myqueue.extractMin();
cout << "After extracting the minimum value Priority Queue has" << endl;
cout <<"Minimum value is " ;
cout << myqueue.min() <<endl; //prints out heap min
system("pause");
return 0;
}
priorityQueue::priorityQueue() //constructor
{
size = CAPACITY;
&data[size];
}
priorityQueue::~priorityQueue() //destructor
{
}
int priorityQueue::getParent(int index) //finds parent
{
return (index - 1) / 2;
}
int priorityQueue::getLeftChild(int index) //finds left child
{
return (2 * index) + 1;
}
int priorityQueue::getRightChild(int index) //find right child
{
return (2 * index) + 2;
}
void priorityQueue::swap(int& item1, int& item2) //swaps value of two variables
{
int temp = item1;
item1 = item2;
item2 = temp;
}
void priorityQueue::heapify(int index) //heapifies the heap
{
int largest = index;
int l = getLeftChild(index);
int r = getRightChild(index);
if (l < size && data[l] > data[index])
{
largest = l;
}
if (r < size && data[r] > data[largest])
{
largest = r;
}
if (largest != index)
{
swap(data[index], data[largest]);
heapify(data[size]);
}
}
void priorityQueue::printArray(int []) //prints array
{
for (int i = 0; i < CAPACITY; i++)
{
cout << data[i] << ", ";
}
}
int priorityQueue::extractMin() //finds min and removes it
{
int min = data[0];
data[0] = data[size - 1];
size - 1;
heapify(data[size]);
return min;
}
int priorityQueue::min() const // finds min
{
return data[0];
}
bool priorityQueue::empty() const // checks if heap is empty
{
if (data == NULL)
{
return true;
}
else
{
return false;
}
}
void priorityQueue::insert(int Item) //inserts values into heap
{
size += 1;
int i = size - 1;
while (i > 0 && data[getParent(i)] < Item)
{
data[i] = data[getParent(i)];
i = getParent(i);
}
data[i] = Item;
}
In your constructor, &data[size]; does nothing. You need to allocate some memory for it, possibly using new - data = new int[size] - or use a smart pointer.
Im just starting to learn C++ programming and for exercise i found this task. I have to write a dynamic, array based integer stack. This is what i have got so far.
#include <iostream>
using namespace std;
class DynamicIntegerStack
{
private:
int *bottom_;
int *top_;
int size_;
public:
DynamicIntegerStack(int n = 20){
bottom_ = new int[n];
top_ = bottom_;
size_ = n;
}
int getSize(){ return size_; }
void push(int c){
if (!full()){
*top_ = c;
top_++;
}
else{
resize(size_ * 2);
*top_ = c;
top_++;
}
}
void resize(int newSize){
//Allocate new array and copy in data
int *newArray = new int[newSize];
memcpy(newArray, bottom_, size_);
// Set the top to the new array
top_ = newArray + (top_ - bottom_);
// Delete old array
delete[] bottom_;
// Update pointers and size
bottom_ = newArray;
size_ = newSize;
cout << "array has been resized" << endl;
}
int num_items() {
return (top_ - bottom_);
}
char pop(){
top_--;
return *top_;
}
int full() {
return (num_items() >= size_);
}
int empty() {
return (num_items() <= 0);
}
void print(){
cout << "Stack currently holds " << num_items() << " items: ";
for (int *element = bottom_; element<top_; element++) {
cout << " " << *element;
}
cout << "\n";
}
~DynamicIntegerStack(){ // stacks when exiting functions
delete[] bottom_;
}
};
int main(){
DynamicIntegerStack s(5);
s.print(); cout << "\n";
s.push(1); s.push(3); s.push(5); s.push(10); s.push(15);
s.print(); cout << "\n";
s.push(20);
s.print(); cout << "\n";
cout << "Popped value is: " << s.pop() << "\n";
s.print(); cout << "\n";
s.push(30);
s.print(); cout << "\n";
s.pop();
s.pop();
s.print(); cout << "\n";
while (!s.empty()) s.pop();
if (s.num_items() != 0) {
cout << "Error: Stack is corrupt!\n";
}
s.print(); cout << "\n";
// destructor for s automatically called
system("pause"); // execute M$-DOS' pause command
return 0;
}
It works fine untill the array is full and i resize it. After that instead of integers it starts printing this.
Thanks in advance for your help.
When you use memcpy, the size of the memory you are copying must be given in bytes.
So, you have to multiply sizeof(int) with your n.
As the title already says, I have a problem with a heap corruption in my C++ code.
I know there are a lot of topics that cover heap corruption problems, and I have visited a lot of them, I read up on a lot of sites about these matters and I've even used Visual Leak Detector to find the location of the memory leak. I still can't seem to figure out why I have a heap corruption.
My code:
#include <iostream>
#include "stdafx.h"
#include "cstdlib"
#include <vld.h>
#include <math.h>
using namespace std;
template <class T>
class PrioQueue
{
private:
int size_;
int tempIndex;
public:
T *bottom_;
T *top_;
PrioQueue(int n =20){
size_ = n;
bottom_ = new T[size_];
top_ = bottom_;
}
void push(T c){
//add the item to the list
*top_ = c;
top_++;
//Save the old stack values in the temp memory
T* values = bottom_;
T tempItem;
int index = num_items();
cout << "Num items: " << index << endl;
cout << "1" << endl;
while(index > 1){
cout << "2" << endl;
if(values[index-1] > values[index-2])
{
cout << "2b" << endl;
tempItem = values[index-2];
values[index-2] = c;
values[index-1] = tempItem;
}
cout << "3" << endl;
index--;
}
cout << "4" << endl;
}
// + operator
PrioQueue* operator+ (PrioQueue que2)
{
PrioQueue<T>* temp = new PrioQueue<T>();
cout << "Created temporary queue" << endl;
for(int i = 0; i <num_items(); i++)
{
cout << "Element in list: " << bottom_[i] << endl;
temp->push(bottom_[i]);
cout << "Temp is now: ";
temp->print();
}
for(int i = 0; i < que2.num_items(); i++)
{
cout << "Element in list: " << que2.bottom_[i] << endl;
temp->push(que2.bottom_[i]);
cout << "Temp is now: ";
temp->print();
}
cout << "Ran loop" << endl;
return temp;
}
// * operator
PrioQueue* operator* (PrioQueue que2)
{
PrioQueue<T>* temp = new PrioQueue<T>();
for(int i = 0; i < num_items(); i++)
{
for(int j = 0; j < que2.num_items(); j++)
{
if(bottom_[i] == que2.bottom_[j])
{
temp->push(bottom_[i]);
break;
}
}
}
return temp;
}
friend ostream& operator<< (ostream& output, PrioQueue& q) {
for(T *element = q.bottom_; element < q.top_; element++)
output << *element << " | ";
return output;
}
int num_items() {
return (top_ - bottom_ );
}
T pop(){
top_--;
return *top_;
}
int full() {
return (num_items() >= size_);
}
int empty() {
return (num_items() <= 0);
}
void print(){
cout << "Print function..." << endl;
cout << "Stack currently holds " << num_items() << " items: " ;
for (T *element=bottom_; element<top_; element++) {
cout << " " << *element;
}
cout << "\n";
}
~PrioQueue(){ // stacks when exiting functions
delete [] bottom_;
}
};
int main()
{
PrioQueue<int> *p1 = new PrioQueue<int>(20);
p1->push(5);
p1->push(2);
p1->push(8);
p1->push(4);
p1->print(); cout << "\n";
PrioQueue<int> *p2 = new PrioQueue<int>(5);
p2->push(33);
p2->push(66);
p2->push(8);
p2->push(5);
p2->print(); cout << "\n";
//add them together
p1->print();
p2->print();
((*p1) + (*p2))->print();
((*p1) * (*p2))->print();
PrioQueue<float> *f1 = new PrioQueue<float>(5);
f1->push(1.1f);
f1->push(5.2f);
f1->push(8.3f);
f1->push(14.4f);
f1->push(17.5f);
f1->print(); cout << "\n";
PrioQueue<float> *f2 = new PrioQueue<float>(4);
f2->push(2.2f);
f2->push(6.7f);
f2->push(10.3f);
f2->push(15.6f);
f2->print();
cout << "\n";
//add them together
((*f1) + (*f2))->print();
// Multiply them.
((*f1) * (*f2))->print();
cout << "\n";
cout << p1 << endl;
cout << f1 << endl;
cout << "Press any key to exit...";
cin.get();
cin.get();
delete p1;
delete p2;
delete f1;
delete f2;
return 0;
}
I already tried removing everything and start at the beginning.
It seemed that changing:
delete [] bottom_;
To:
delete bottom_;
Fixed it, but that was before I pushed a value to the array.
Could some of you please enlighten me on what is wrong. It would be very much appreciated.
Thank you in advance,
Greatings Matti Groot.
The change you mention leads to undefined behavior. If you got something with new[] you must pass it to delete[]. Plain delete is only good for what you got with plain new.
Your operator + and * creates new objects and return pointer to it. I don't see any attempt to delete those objects, so no wonder you have leaks. (It counts as bad design to return pointers-with-obligation for no good reason, even more so from operators on objects that should produce objects.)
1. Stop using new everywhere.
If you want a new Object to work with, create one on the stack.
PrioQueue *p1 = new PrioQueue(20); // NO!
PrioQueue q1(20); // YES!
2. Consider to use unsigned values where usigned values are appropriate.
3. In your operator+() you'll have to set the size of the new temporary Queue appropriately.
4. See Blastfurnace's answer regarding resource managment and operator design.
5. Try to find out what resource acquisition is initialization (RAII) is and use this knowledge.
I addressed some of your issues
template <class T>
class PrioQueue
{
private:
size_t size_;
T *bottom_;
T *top_;
public:
PrioQueue (void)
: size_(20U), bottom_(new T[20U]), top_(bottom_)
{
}
PrioQueue(size_t n)
: size_(n), bottom_(new T[n]), top_(bottom_)
{
}
PrioQueue(PrioQueue<T> const & rhs)
: size_(rhs.size_), bottom_(new T[rhs.size_]), top_(bottom_)
{
for (size_t i=0; i<size_; ++i)
{
bottom_[i] = rhs.bottom_[i];
}
}
PrioQueue<T> & operator= (PrioQueue<T> rhs)
{
swap(rhs);
}
void push (T c)
{
// check if its full
if (full()) throw std::logic_error("full");
//add the item to the list
*top_ = c;
top_++;
// there is no point operating on a new pointer named "values" here
// your still addressing the same memory, so you can just operate on bottom_ instead
for (size_t index = num_items()-1; index > 0; --index)
{
if(bottom_[index] > bottom_[index-1])
{
std::swap(bottom_[index], bottom_[index-1]);
}
}
}
// + operator
PrioQueue<T> operator+ (PrioQueue<T> const & que2)
{
// you need a temporary queue that is large enough
// so give it the proper size (sum of both sizes)
PrioQueue<T> temp(num_items() + que2.num_items());
std::cout << "Created temporary queue" << std::endl;
for(size_t i = 0; i <num_items(); i++)
{
std::cout << "Element in list: " << bottom_[i] << std::endl;
temp.push(bottom_[i]);
std::cout << "Temp is now: ";
temp.print();
}
for(size_t i = 0; i < que2.num_items(); i++)
{
std::cout << "Element in list: " << que2.bottom_[i] << std::endl;
temp.push(que2.bottom_[i]);
std::cout << "Temp is now: ";
temp.print();
}
std::cout << "Ran loop" << std::endl;
return temp;
}
// * operator
PrioQueue<T> operator* (PrioQueue<T> const & que2)
{
size_t que1_items = num_items(), que2_items = que2.num_items();
PrioQueue<T> temp(que1_items);
for (size_t i = 0U; i < que1_items; ++i)
{
for(size_t j = 0U; j < que2_items; ++j)
{
if(bottom_[i] == que2.bottom_[j])
{
temp.push(bottom_[i]);
}
}
}
return temp;
}
friend std::ostream& operator<< (std::ostream& output, PrioQueue<T> & q)
{
for(T *element = q.bottom_; element < q.top_; element++)
output << *element << " | ";
return output;
}
size_t num_items(void) const
{
return size_t(top_ - bottom_ );
}
T pop (void)
{
// you actually popped of the last element and returned the next
// i think it is likely you want to return the element you pop off
return *(top_--);
}
// why int? full or not is a rather boolean thing i guess
bool full (void) const
{
// num_items() > size_ must not happen!
return (num_items() == size_);
}
bool empty(void) const
{
// an unsigned type cannot be < 0
return (num_items() == 0);
}
void swap (PrioQueue<T> & rhs)
{
std::swap(size_, rhs.size_);
std::swap(bottom_, rhs.bottom_);
std::swap(top_, rhs.top_);
}
void print (void) const
{
cout << "Print function..." << endl;
cout << "Stack currently holds " << num_items() << " items: " ;
for (T * element=bottom_; element<top_; ++element)
{
cout << " " << *element;
}
cout << endl;
}
~PrioQueue()
{
delete [] bottom_;
}
};
int main()
{
PrioQueue<int> q1;
q1.push(5);
q1.push(2);
q1.push(8);
q1.push(4);
q1.print();
PrioQueue<int> q2;
q2.push(33);
q2.push(66);
q2.push(8);
q2.push(5);
q2.print();
std::cout << "Plus: " << std::endl;
PrioQueue<int> q_plus = q1+q2;
q_plus.print();
std::cout << "Multi: " << std::endl;
PrioQueue<int> q_multi = q1*q2;
q_multi.print();
}
Your class manages a resource (memory) but you don't correctly
handle copying or assignment. Please see: What is The Rule of
Three?.
The design of your operator+() and operator*() is unusual and
leaks memory. Returning PrioQueue* makes it cumbersome or
impossible to properly free temporary objects. Please see: Operator
overloading
You might be interested in The Definitive C++ Book Guide and List to learn the language basics and some good practices.
I suggest you try re-writing this without using new or delete. Change your * and + operators to return a PrioQueue. Change the PrioQueue to use a vector<T> instead of an array. You can then focus on writing your own priority queue. Make sure you use the standard priority queue if you actually need one though.
((*p1) + (*p2))->print();
and statements like these .. Your + & * operator returns a new'ed PrioQueue . So you are not deleting it anywhere .
So try to take return value in a temp PrioQueue pointer and call delete on it as well .
I'm in the process of learning how to create Stacks and linked lists. The program that I'm writing right now focuses on a template stack class. Everything was going smoothly when I made a stack of int, but my program started crashing when I started implementing a stack of char. To be specific it started messing up when I tried to implement a pop action on the stack of char.
Can you guys please verify that I'm doing this correctly and also let me know what I'm doing wrong with char stack?
Here's my code:
#include<iostream>
using namespace std;
#ifndef STACK_H
#define STACK_H
//STACK CLASS
template<typename T>
class Stack
{
public:
Stack(int = 10);
~Stack(){ delete stackPtr;};
bool isEmpty() const
{ return top == -1; }
bool isFull() const
{ return top == size - 1; }
//push and pop
bool push(const T&);
bool pop(T&);
private:
int size;
int top;
T *stackPtr;
};
//CONSTRUCTOR
template<typename T>
Stack<T>::Stack(int newSize)
: top(-1), size(newSize),
stackPtr(new T[size]) //allocate array using ptr ********
{
//empty constructor
};
//PUSH VALUES ONTO STACK
template<typename T>
bool Stack<T>::push(const T &pushVal)
{
if(!isFull())
{
stackPtr[++top] = pushVal;
return true;
}
return false;
};
//POP VALUES OFF OF STACK
template<typename T>
bool Stack<T>::pop(T &popVal)
{
if(!isEmpty())
{
popVal = stackPtr[top--];
return true;
}
return false;
};
#endif
//DRIVER
int main()
{
//STACK OF INT
Stack<int> intStack(5);
int intValue = 1;
cout << "Pushing values onto intStack: " << endl;
while(intStack.push(intValue))
{
cout << intValue << ' ';
intValue++;
}
cout << "\nStack is full, cannot push..."
<< endl << endl;
cout << "Popping values off of intStack: " << endl;
while(intStack.pop(intValue))
cout << intValue << ' ';
cout << "\nStack is empty, cannot pop..."
<< endl;
//STACK OF CHAR
Stack<char> charStack(5);
string greeting = "hello";
int strSize = greeting.length();
cout << "\nPushing values onto charStack: " << endl;
for(int i = 0; i < strSize; i++)
{
charStack.push(greeting.at(i));
cout << greeting.at(i) << ' ';
}
cout << endl;
cout << "Popping values off of charStack: " << endl;
for(int i = (strSize - 1); i >= 0; i++) //PROBLEM OCCURS
{
charStack.pop(greeting.at(i));
cout << greeting.at(i) << ' ';
}
system("pause");
}
for(int i = (strSize - 1); i >= 0; **i--**) //PROBLEM not anymore
{
charStack.pop(greeting.at(i));
cout << greeting.at(i) << ' ';
}
Probably it's not the source of your particular problem, but you really should use
delete[] stackPtr
instead of delete stackPtr in your destructor. Wikipedia explains why