C++ Stack Push/Print Implementation - c++

I'm trying to make a stack implementation in C++ but when I try to print the stack,
it just prints the first element instead of the whole stack.
I've tested it and I'm pretty sure that my Push function is right, but I'm not sure.
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
int main(){
StackElement *stack = new StackElement();
stack->data = 20;
stack->Push(30,stack);
stack->Push(40,stack);
stack->Print(stack);
}
#include <stdio.h>
#include <stdlib.h>
class StackElement{
public:
int data;
StackElement* next;
StackElement();
void StackElement::Push(int value, StackElement *oldElement);
void StackElement::Print(StackElement *element);
};
StackElement::StackElement(){
next = NULL;
}
void StackElement::Push(int value, StackElement *oldElement){
StackElement *newElement = new StackElement();
newElement->data = value;
printf("Element added to stack: %d\n", newElement->data);
oldElement->next = newElement;
}
void StackElement::Print(StackElement *element){
while(element->next != NULL){
printf("%d\n",element->data);
element = element->next;
}
}

Your code kept loosing the previous pushed element, leaking memory, as #Beta described.
I suggest comparing my code below to your code. You'll see, I've moved the handling of the stack elements outside, just to be able to keep track of the first element. Also, notice that there is no pointer in the main function. That is what we expect from a class.
Stack_element is a struct really as there's not much point in making the Stack_element itself encapsulated, it is just an implementation detail of Stack.
So here's my code derived from yours
#include<iostream>
struct Stack_element{
int data;
Stack_element*next;
};
class Stack{
private:
Stack_element*last_data, first_data;
public:
Stack():last_data(NULL), first_data(NULL){}
void push(int data);
void print() const;
};
void Stack::push(int data)
{
Stack_element*p=new Stack_element();
p->data=data;
p->next=NULL;
if(last_data)
last_data->next=p;
else // empty stack
first_data=p;
last_data=p;
}
void Stack::print()
{
for(Stack_element*p=first_data;p;p=p->next)
std::cout << p->data << std::endl; // ** Do not use printf in c++. Ever. **
}
and in the main function just call
Stack stack;
stack.push(30);
stack.push(40);
stack.print();
REMARK: For a C++ish print you might want to do an ostream& print(ostream& os) instead, where
std::ostream& Stack::print(std::ostream& os)
{
for(Stack_element*p=first_data;p;p=p->next)
os << p->data << std::endl;
return os;
}
just to be able to write std::cout << stack.print() << std::endl;. The benefit of this is that you can easily redirect to a file.
std::ofstream ofs("yourfile.txt");
ofs << stack.print() << std::endl; // prints to file instead of screen.

Suppose this much works as planned:
StackElement *stack = new StackElement();
stack->data = 20;
stack->Push(30,stack);
Now your data looks like [20]->[30]
Now you attempt
stack->Push(40,stack);
So the Push method creates a new StackElement, gives it the value 40, and sets Stack to point to it: [20]->[40]. Notice that [30] has been lost.
Then the Print function:
while(element->next != NULL){
printf("%d\n",element->data);
element = element->next;
}
If there is only one element (whose next is NULL), this function will quit and print nothing. If there are two, this function will print the data of the first, then quit. And there will never be more than two, as long as Push has that bug.

Related

Redefine a Node of linked list: std::string

I am currently working on a school project, the material is new to me at the moment, basically, we are creating a Robot Guider that tracks their movement, distance, speed, etc... one of the functions that we are required to make is renaming a robot, however, they are stored in Node.
I have spent some time looking around for a quick solution and I am a little confused by the examples online. If someone could please help but also explain their logic that would be greatly appreciated.
we are using two different classes to track all of the information
-----CLASS #1:
#ifndef RobotList_hpp
#define RobotList_hpp
#include "Robot.hpp"
#include <stdio.h>
#include <iostream>
class RobotList{
private:
class Node{
public:
Robot* val;
Node* next = nullptr;
Node(std::string aName) {
val = new Robot;
val->setName(aName);
}
};
Node* head = nullptr;
Node* tail = nullptr;
public:
RobotList() = default;
~RobotList();
void display() const;
bool isEmpty();
Robot* find_nth();
void updateList();
void addNode(std::string name);
void deleteNode(std::string name);
void rename();
void robotDist() const;
};
#endif /* RobotList_hpp */
---CLASS #2:
#ifndef Robot_hpp
#define Robot_hpp
#include <stdio.h>
#include <iostream>
#include <algorithm>
class Robot{
private:
int x, y, curSpeed, totDist;
std::string name; char lastCommand;
bool stop_; int off_or_on;
public:
std::string getName() { return name; }
void setName(std::string a) {
this->name = a;
}
int getTotDist() { return totDist; }
void moveRobot();
int findRobot();
};
#endif /* Robot_hpp */
void RobotList::rename(){
std::string new_name;
std::cout << "Which robot do you want to rename?"<< std::endl;
std::cin >> new_name;
Node* temp = head;
while(!head){
if(temp->val->getName() == new_name){
// update list with user input new_name
// reassign a node that holds a string value
}
}
temp = temp->next; // rest of list til nullptr
}
This is what I tried to do but it was not operating properly.
I wrote out two comments on what I am trying to do. Thanks.
The problem is the while loop.
Head is a pointer to the first element so !head is true only when the list is empty, which is not what you want. Head should not be modified because we will lose the start of the list, that's why we have the temp.
The loop should stop at the end of the list, we know we reached the end when temp is nullptr. This is convenient because it makes sure we never dereference a null pointer. temp = temp->next; should be placed inside the loop so that it doesn't get stuck at the first element.
std::string old_name, new_name;
std::cout << "Which robot do you want to rename?"<< std::endl;
std::cin >> old_name; // name to search for
std::cout << "Enter new name:"<< std::endl;
std::cin >> new_name; // new name for the robot with old_name
Node* temp = head; // temp = first element(node) of the list
while(temp){ // while we haven't reached the end of the list
if(temp->val->getName() == old_name){
temp->val->setName(new_name);
break; // break if you only want to modify the first occurrence
}
temp = temp->next; // move to the next node
}
Also try to use const references for passing objects whenever possible, otherwise you create a lot of unwanted copies.

C++ Pointer target returning wrong value

I am a fairly experience C# programmer and trying to help out a friend with a C++ application that creates a Stack object. It has been well over 13 years since I've even seen C++ and I am having a damn fine time trying to recall the proper way to do this. It took me a bit to get up to speed on the Header/CPP distinction again, so there may be issues in there even. Here is my problem:
//Stack.h
#ifndef __STACK_INCLUDED__
#define __STACK_INCLUDED__
#include "Node.h"
class Stack
{
private:
/// Going to be the pointer to our top node
Node* m_topNode;
/// Running count of elements
int m_count;
public:
///Constructor
Stack();
///Allows us to retrieve the top value from the stack
/// and remove it from the stack
int Pop();
.
.
.
};
#endif
Below is the CPP that matches the header. I am doing in here JUST for debugging at the moment. I am also fully qualifying everything because I was not sure if that is causing issues with the pointers and loss of references.
//Stack.cpp
#include "stdafx.h"
#include "Stack.h"
#include <iostream>
Stack::Stack(){
m_count = 0;
m_topNode = NULL;
}
void Stack::Push(int Value){
std::cout << "\nPushing Value: ";
std::cout << Value;
std::cout << "\n";
if ( Stack::m_topNode )
{
std::cout << "TopNode Value: ";
std::cout << Stack::m_topNode->data;
std::cout << "\n";
}
std::cout << "\n";
Node newNode(Value, NULL, Stack::m_topNode);
Stack::m_topNode = &newNode;
Stack::m_count++;
}
The node class is a pretty simple entity. Just needs to store a value and the pointers on either side. I know I don't need to track in both directions for a Stack but I wanted to make this something that was easily changed to a Queue or similar construct.
//Node.h
#ifndef __NODE_INCLUDED__
#define __NODE_INCLUDED__
class Node
{
private:
public:
///Constructor allows us to specify all values.
/// In a stack I expect NextNode to be NULL
Node(int Value,Node* NextNode, Node* PreviousNode);
///Pointer to the next node
Node* Next;
///Pointer to the previous node
Node* Prev;
///Value to be stored
int data;
};
#endif
Very simple implementation:
//Node.cpp
#include "stdafx.h"
#include "Node.h"
Node::Node(int Value, Node* NextNode, Node* PreviousNode){
data = Value;
Next = NextNode;
Prev = PreviousNode;
}
My main is just about sending 2 values to the stack right now via Push and seeing what the values are printing:
#include "stdafx.h"
#include "Node.h"
#include "Stack.h"
using namespace std;
int main(){
Stack s = Stack();
for ( int i = 0; i < 2; i++ ){
s.Push(i * 10);
}
int blah;
cin >> blah; //Stall screen
return 0;
}
Here is the Output:
Pushing Value: 0
<blank line>
Pushing Value: 10
TopNode Value: -858993460
When I hit Node newNode(Value, NULL, Stack::m_topNode) in the debugger I can see it tracking the proper value in the current node, but m_topNode references a really odd value. I'm hoping it's very obvious that I'm doing something dumb as I don't remember this being this tricky when I did it years ago. Appreciate any help/insight to my incorrect manners.
Node newNode(Value, NULL, Stack::m_topNode);
Stack::m_topNode = &newNode;
Stack::m_count++;
This is your problem. You allocate the new node on the current stack, and then put the pointer into the linked list of nodes. This pointer will be invalid as soon as your stack frame returns, and all hell breaks lose. ;)
You need to allocate the node with new.
As stated by Norwæ, you need to allocate your newNode with "new" because if you dont, your newNode is static and will be out of scope at the end of the Push function.
You also need to call your private members without the "Stack::" as this is used in C++ only to access static class members and functions. replace "Stack::m_topNode" for "m_topNode" only, and Stack::m_count for m_count.
Here is a working Push function :
void Stack::Push(int Value){
std::cout << "\nPushing Value: ";
std::cout << Value;
std::cout << "\n";
if ( m_topNode )
{
std::cout << "TopNode Value: ";
std::cout << m_topNode->data;
std::cout << "\n";
}
std::cout << "\n";
Node * newNode = new Node(Value, NULL, m_topNode);
m_topNode = newNode;
m_count++;
}
This line:
std::cout << Stack::m_topNode->data;
happens before
Node newNode(Value, NULL, Stack::m_topNode);
Stack::m_topNode = &newNode;
Stack::m_count++;
So you're trying to print an uninitialized value. Reverse these and see what happens.

Template Stack and LIFO C++

So I'm trying to learn about Templates and the Fifo and Lifo stack stuff. I've been playing around with some code that deals with this, and I can get the int data to do what I want for testing but I can't for the life of me figure out how to get this to work with a string.
The way I have the code keeps crashing on me, but doesn't give me any errors, so I thought I'd pop in here and see if anybody could tell me what I'm doing wrong. Here's my code:
-----------//my header//---------------------
#include <stdlib.h>
#include <iostream>
#include <string>
#ifndef STACK_H_
#define STACK_H_
template<class T>
class StackTest
{
private:
unsigned int maxSize;
T *stackData;
int top;
public:
StackTest(int size){
stackData = new T[size];//to hold the T ‌type data items
top = -1;//no items on the stack
maxSize = size;//set maximum size that stack can hold
}
virtual ~StackTest(){}
int count(){
return top + 1;
}
bool isEmpty(){
return top == -1 ? true : false;
}
bool isFull(){
return top == maxSize - 1 ? true : false;
}
T* peek(){
if(!isEmpty())//check for empty
return &stackData[top - 1];
}
T* pop(){
if(!isEmpty()){
top -= 1;//decrease the top by 1 to indicate the delete
return &stackData[top];//return deleted item
}
return NULL;
}
void push(T* item){
stackData[top++] = *item;//insert to data array and increase the top by one
}
};
#endif /* STACK_H_ */
-----------//my main//---------------
#include <iostream>
#include <string>
#include "Pair.h"
using namespace std;
int main() {
int dataTest;
string strTest;
StackTest<int> intStack(10);
StackTest<string> stringStack(50);
//Insert data into the stack
dataTest = 3;
intStack.push(&dataTest);
dataTest = 4;
intStack.push(&dataTest);
dataTest = 5;
intStack.push(&dataTest);
dataTest = 6;
intStack.push(&dataTest);
strTest = "test";
stringStack.push(&strTest);
//Show the top item
cout << *intStack.peek() << endl;
cout << *stringStack.peek() << endl;
//Pull the top item out (twice)
intStack.pop();
intStack.pop();
//Show the new top item
cout << *intStack.peek() << endl;
return 0;
}
So if anyone feels like giving me some pointers I would really appreciate it, thanks.
There are a few issues with your implementation. One of the most subtle is in the push() member function:
void push(T* item){
stackData[top++] = *item; //insert to data array and increase the top by one
// ^^
// You want pre-increment here!
}
This is incrementing top and using the old value as an index into stackData. Since top is -1 when the stack is empty, your program is actually doing:
stackData[-1] = *item;
top = 0;
Needless to say that the first assignment results in undefined behavior.
Another source of undefined behavior is the peek() member function, which does not return anything when the stack is empty:
T* peek(){
if(!isEmpty())//check for empty
return &stackData[top - 1];
}
Per paragraph 6.6.3/2 of the C++11 Standard:
[...] Flowing off the end of a function is equivalent to a return with no value; this results in undefined
behavior in a value-returning function.
But that's not the only issue: the other problem is with the access of stackData:
return &stackData[top - 1];
When top is not equal to or greater than one, this will also result in undefined behavior, since you would be taking the address of a (non-)object located at a negative address in the array.
Also, I suggest to rewrite isEmpty() and isFull() as follows:
bool isEmpty(){
return (top == -1);
}
bool isFull(){
return (top == maxSize - 1);
}
As a general advice, consider not using the value -1 for top when the stack is empty. As Ben Voigt mentions in the comments, this is leading you to a lot of off-by-one errors.
Also, as pointed out by DyP, your destructor is not freeing the memory allocated in the constructor, so your StackTest object is leaking memory. And after doing that, since we're at it, you may want to have a look at the so-called Rule of Three, that your program would be violating.

Destructor, doesn't delete my object

I have big problem- namely my destructor doesn't delete object, in my code which i will paste underneath in main when i call l3.~list(); it removes only singly linked list(which is good), but it doesn't remove char* name, even though I am stating in my destructor delete [] name;. Any ideas whats wrong?
Here is the code;
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
class list{
struct lista
{
int num;
char* word;
lista* next;
};
lista* head;
char* name;
public:
list(char* name1){head=NULL;name=new char[strlen(name1)+1];strcpy(name,name1);}
char getChar(int key, int index);
void setChar(int key, int index, char c);
void insert(int number,char* txt);
void remove(int number);
void print();
list(const list &o);
list& operator=(const list &x);
~list();
};
void list::insert(int number,char* txt){
lista* ptr,*tmp;
ptr=head;
lista* newlista=new lista;
newlista->num=number;
newlista->next=NULL;
newlista->word= new char[strlen(txt)+1];
strcpy(newlista->word,txt);
if(head==NULL){
head=newlista;
newlista->next=NULL;
}
else while(ptr!=NULL){
if(strcmp(txt,ptr->word)>=0){
if(ptr->next!=NULL && strcmp(txt,ptr->next->word)<=0)
{
tmp=ptr->next;
ptr->next=newlista;
newlista->next=tmp;
break;
}
else if(ptr->next!=NULL && strcmp(txt,ptr->next->word)>0)
ptr=ptr->next;
else
{
//next is empty
ptr->next=newlista;
break;
}
}
else{
//txt mniejszy niz w 1szym elemencie
newlista->next=head;
head=newlista;
break;
}
}
return;
}
void list::print(){
cout<<name<<";"<<endl;
lista *druk;
druk=head;
while(druk!=NULL){
cout<<"txt: "<<druk->word<<" | "<<"num: "<<druk->num<<endl;
druk=druk->next;
}
cout<<endl;
return;
}
void list::remove(int number){
if(head==NULL)
return;
if(head->num==number){
lista* ptr=head;
head=head->next;
delete [] ptr->word;
delete ptr;
return;
}
lista* ptr=head;
while(ptr->next!=NULL && ptr->next->num!=number)
ptr=ptr->next;
if(ptr->next==NULL){
cout<<number<<" element not found"<<endl;
return;
}
lista* todelete=ptr->next;
ptr->next=todelete->next;
delete [] todelete->word;
delete todelete;
return;
}
list::list(const list &o)
{
lista *xtr = o.head;
head=NULL;// bez tego nie działa
lista *etr=head;// nastawic etr na head?
while (xtr)
{
lista* ntr = new lista;
if (!ntr)
{
cerr << "list::CopyConstructor: Allocation memory failure!";
cerr << endl;
break;
}
ntr->num = xtr->num;
ntr->word= new char[strlen(xtr->word)+1];
strcpy(ntr->word,xtr->word);
ntr->next = NULL;
if (head)
etr->next = ntr;
else
head = ntr;
etr = ntr; // keep track of the last element in *this
xtr = xtr->next;
}
name = new char[strlen(o.name)+5];
strcpy(name,o.name);
strcat(name,"Copy");
}
list& list::operator=(const list &x)
{
if(this==&x)
return *this;
lista *etr=head;
while(etr) // removing list from this
{
etr=etr->next;
delete head;
head=etr;
}
lista *xtr=x.head;
while(xtr)
{
int copied=xtr->num;
lista *ntr= new lista;
ntr->word=new char[strlen(xtr->word)+1];
if (!ntr)
{
cerr << "list::operator=: Allocation memory failure!" << endl;
break;
}
ntr->num=copied;
strcpy(ntr->word,xtr->word);
ntr->next=NULL;
if (!head)
head = ntr;
else
etr->next = ntr;
etr = ntr; // keep track of the last element in *this
xtr = xtr->next;
}
char *name=new char[strlen(x.name)+1];
strcpy(name,x.name);
return *this;
}
list::~list()
{
cout<<"Object with name:"<<name<<" destroyed!"<<endl;
delete [] name;
lista *dtr=head;
while(dtr) // removing lista from this
{
dtr=dtr->next;
delete [] head->word;
delete head;
head=dtr;
}
}
void f();
void f(){
list o("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
o.insert(4,"kazio");
o.insert(100,"312jh31io2");
o.insert(34,"kz31231azio");
o.insert(1020,"123213312jh31io2");
o.insert(213123,"z3213io");
o.insert(1100,"zdrf312jh31io2");
o.print();
}
int main(){
list l1("lista1");
l1.insert(5,"Endian");
l1.insert(7,"Endianness");
l1.insert(100,"Hexediting");
l1.insert(34,".mil");
l1.print();
list l2(l1); // usage of CC - the same as list l2=l1;
l2.print();
l2.remove(5);
l2.print();
l1.print();
list l3("asajnment");
l3=l2=l1;
l3.print();
l2.print();
f();
l3.print();
l3.~list(); // here i use destructor on l3
l3.print(); // l3 is being printed with weird name, even though it should be destroyed
getchar();
return 0;
}
Calling any method after invoking destructor results in undefined behaviour - it may or may nor work and it can produce strange results.
Also, you are not supposed to call the destructor directly:
When the object is allocated on stack, it is destroyed automatically when the scope ends. (Scope is the thing between braces {})
When the object is allocated on heap, using new, it should be destroyed using delete.
C++ destructors are not like deallocation functions as you might write in C. They're better: in the RAII idiom, you have destruction of your objects scheduled to the very moment they exit scope. That means you usually don't have to care for freeing resources at all: just wait until the object is no longer needed (because it can't be accessed), at that points it gets automatically removed (which includes calling the destructor, yes, and that's the only way in which it may be called safely). So well-written C++ is in many ways as good as garbage-collected languages, but without some of their drawbacks.
The easiest way to get the benefits of RAII is to use standard containers and smart pointers. In your case, replace lista* next with std::unique_ptr<lista> next and char* word with std::string word, and all is fine without the need to define a destructor at all.
There is so much wrong with this code that I don't know where to start...
use std::string
use a std::map to associate int values with the strings. This will pretty much already do what you want.
don't call the destructor for anything that was not new'd. To delete something use delete/delete[] and don't call the destructor directly. If you do use new, use the RAII idiom using managing objects such as std::unique_ptr or std::shared_ptr to avoid having to manually call delete/delete[] and to write exception safe code
Here is a somewhat improved version. Notice that there is not a single call to new/delete.
#include <iostream>
#include <string>
#include <map>
#include <cstdio>
class list
{
public:
explicit
list( std::string n ) : name( n ) {}
~list() { std::cout << "~list:" << name << std::endl; }
void list::insert(int number, std::string const& txt ){
items.insert( std::make_pair(number,txt));
}
void list::remove(int number){
items.erase( number );
}
void print( ){
std::cout << name << ";" << std::endl;
for( Items::const_iterator it = items.begin(), end = items.end(); it != end; ++it )
{
std::cout << "num: " << it->first << " | " << "txt: " << it->second << std::endl;
}
std::cout << std::endl;
}
private:
typedef std::map<int,std::string> Items;
Items items;
std::string name;
};
int main()
{
list l1( "lista1" );
l1.insert( 5, "Endian");
l1.insert( 7, "Endianness");
l1.insert( 100, "Hexediting");
l1.insert( 34, ".mil");
// extra scope so the destructor of l2 is called before call to getchar
{
list l2( l1 );
l2.remove( 5 );
l2.print();
}
l1.print();
getchar();
return 0;
}
One way of making sure that your members are not being accessed by mistake after destruction is to set all pointers to NULL after deleting them.
That way, you're assured that nobody can get to your sensitive data afterwards, because you're no longer pointing to it. And you can call the destructor again without bad side effects, because calling delete on a NULL pointer is allowed and does nothing.
If you print the memory state of your object after deleting it, you will see the value stay until you don't alloc a new object. The memory allocated for your program can only go bigger. When you delete data, they are not set to '0', just marked as free for the next alloc object.
EDIT: I mean if you create a new object with uninitialized values just after free, he can get back the old value stored in memory.

Memory leak in trivial stack implementation

I'm decently experienced with Python and Java, but I recently decided to learn C++. I decided to make a quick integer stack implementation, but it has a massive memory leak that I can't understand. When I pop the node, it doesn't seem to be releasing the memory even though I explicitly delete the old node upon poping it. When I run it, it uses 150mb of memory, but doesn't release any of it after I empty the stack. I would appreciate any help since this is my first foray into a language without garbage collection. This was compiled with gcc 4.3 on 64-bit Kubuntu.
//a trivial linked list based stack of integers
#include <iostream>
using namespace std;
class Node
{
private:
int num;
Node * next;
public:
Node(int data, Node * next);
int getData();
Node * getNext();
};
Node::Node(int data, Node * next_node)
{
num = data;
next = next_node;
}
inline int Node::getData()
{
return num;
}
inline Node* Node::getNext()
{
return next;
}
class Stack
{
private:
unsigned long int n;
Node * top;
public:
Stack(int first);
Stack();
void push(int data);
int pop();
int peek();
unsigned long int getSize();
void print();
void empty();
};
Stack::Stack(int first)
{
Node first_top (first, NULL);
top = &first_top;
n = 1;
}
Stack::Stack()
{
top = NULL;
n = 0;
}
void Stack::push(int data)
{
Node* old_top = top;
Node* new_top = new Node(data,old_top);
top = new_top;
n++;
}
int Stack::pop()
{
Node* old_top = top;
int ret_num = old_top->getData();
top = old_top->getNext();
delete old_top;
n--;
return ret_num;
}
inline int Stack::peek()
{
return top->getData();
}
inline unsigned long int Stack::getSize()
{
return n;
}
void Stack::print()
{
Node* current = top;
cout << "Stack: [";
for(unsigned long int i = 0; i<n-1; i++)
{
cout << current->getData() << ", ";
current = current->getNext();
}
cout << current->getData() << "]" << endl;
}
void Stack::empty()
{
unsigned long int upper = n;
for(unsigned long int i = 0; i<upper; i++)
{
this->pop();
}
}
Stack createStackRange(int start, int end, int step = 1)
{
Stack stack = Stack();
for(int i = start; i <= end; i+=step)
{
stack.push(i);
}
return stack;
}
int main()
{
Stack s = createStackRange(0,5e6);
cout << s.peek() << endl;
sleep(1);
cout << "emptying" <<endl;
s.empty();
cout << "emptied" <<endl;
cout << "The size of the stack is " << s.getSize()<<endl;
cout << "waiting..." << endl;
sleep(10);
return 0;
}
How do you KNOW the memory isn't being released? The runtime library will manage allocations and may not release the memory back to the OS until the program terminates. If that's the case, the memory will be available for other allocations within your program during its execution.
However.... you seem to have other problems. My C++ is really rusty since I've been doing Java for 15 years, but in your Stack::Stack constructor you're allocating a Node instance on the system stack and then storing a reference to it in your "Stack". That Node instance goes out of scope when the constructor ends, leaving a dangling pointer.
Stack::Stack(int first)
{
Node first_top (first, NULL);
top = &first_top;
n = 1;
}
This is wrong , you cant assign address of a local object to class member( top ) , since local objects get destroyed when function returns.
Create a node on heap rather than stack , do something like this :
Stack::Stack(int first)
{
top = new Node(first, NULL);
n = 1;
}
And Make the concept of link list clear and use pen and paper if you can do so.
Your Stack::Push(int) operation seems buggy check it out what you have forget to do.
My suggestion is try to implement generic stack with the help of template ,so it will work for all data type .
When createStackRange() returns it'll return a copy of the Stack using the compiler-generated copy constructor which just makes a bitwise copy (i.e., it'll copy the pointer to the first node and the size.)
More seriously, you're missing the destructor for the Stack class. Ideally you'd have it walk the list and call delete on each Node. The Stack object created on the processor stack will automatically be cleaned up automatically when main() exits, but without a destructor, the nodes will still be allocated when the program ends. You probably want something like this for it:
Stack::~Stack()
{
while ( top )
{
Next *next = top->getNext();
delete top;
top = next;
}
}
The way to think of it is that the C++ compiler will automatically generate copy constructors and destructors for you, but they're normally shallow. If you need deep behavior you've got to do it implement it yourself somewhere.
After poring over the code, I couldn't find the leak so I compiled it and ran it in a debugger myself. I agree with Jim Garrision - I think you're seeing an artifact of the runtime rather than an actual leak, because I'm not seeing it on my side. The issues pointed out by NickLarsen and smith are both actual issues that you want to correct, but if you trace the code through, neither should actually be causing the problem you describe. The code smith singles out is never called in your example, and the code Nick singles out would cause other issues, but not the one you're seeing.
Creat a stub to test your code and user Memory Analysis tool like "Valgrind". This will find out memory leaks and corruptions for you.
check man-pages for more information.
Note that you should only roll your own stack for educational purposes. For any real code, you should use the stack implementation that comes with the C++ standard library...