WIll the stack pointer in the function would be formal parameter? - c++

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
struct node
{
int data;
struct node *next;
};
struct stack
{
node *head;
};
void push(struct stack *stack1,int data)
{
struct node *new_node= new node;
new_node->data=data;
if(stack1->head!=NULL)
new_node->next=stack1->head;
else
new_node->next=NULL;
stack1->head=new_node;
}
void pop(struct stack *stack1)
{
node *temp= new node;
if(stack1->head==NULL)
cout<<"EMPTY"<<endl;
else
{
temp=stack1->head;
stack1->head=(stack1->head)->next;
int t;
t=temp->data;
free(temp);
cout<<t<<" ";
}
}
void show(struct stack *stack1)
{
node *new_node=new node;
new_node=stack1->head;
if(stack1->head==NULL)
{
cout<<"EMPTY"<<endl;
return;
}
while(new_node!=NULL)
{
cout<<new_node->data<<" ";
new_node=new_node->next;
}
}
void peek(struct stack *stack1)
{
if(stack1->head==NULL)
cout<<"EMPTY";
else
cout<<stack1->head->data<<" ";
}
int main()
{
int temp,temp2;
struct stack *stack1=new stack;
stack1->head=NULL;
while(1)
{
cin>>temp;
switch(temp)
{
case 0: exit(0);
case 1: cin>>temp2;
cout<<endl;
push(stack1,temp2);
break;
case 2: pop(stack1);
cout<<endl;
break;
case 3: peek(stack1);
cout<<endl;
break;
case 4: show(stack1);
cout<<endl;
break;
}
}
return 0;
}

From the C++ Standard
1.3.14 [defns.parameter]
parameter formal argument
formal parameter
object or reference declared as part of a
function declaration or definition or in the catch clause of an
exception handler that acquires a value on entry to the function or
handler
From the C Standard
3.16 1 parameter
formal parameter formal argument (deprecated)
object declared as part of a function declaration or definition that
acquires a value on entry to the function, or an identifier from the
comma-separated list bounded by the parentheses immediately following
the macro name in a function-like macro definition
Thus for example in this function declaration
void push(struct stack *stack1,int data);
stack1 and data are formal parameters. They require values (arguments) on entry to the function.
Take into account that because stack1 is declared as pointer to struct stack then any changes of the object pointed to by the pointer will be keep in the object after exiting the function.

Related

Why accessing variable declared locally from outside is working?

In tree, while taking input (inside takeInput function), tree node was made using dynamic allocation, but I tried doing it statically, but as tree node were declared inside a function locally it should have not worked because its a local variable (I was expecting a error). But Why am I able print it even after that:
NOTE: this code takes input recursively (and may not be the best way)
#include<bits/stdc++.h>
using namespace std;
template <typename T>
class treeNode{
public:
T data;
vector <treeNode<T>> children;
treeNode(T data){
this->data=data;
}
};
treeNode<int> takeInput(){
int rootdata;
cout<<"Enter Node"<<endl;
cin>>rootdata;
// treeNode<int>* root= new treeNode<int>(rootdata);
treeNode<int> root(rootdata); //Static Allocation
cout<< "Enter Number of children of "<<rootdata<<endl;
int n;
cin>>n;
for(int i=0;i<n;i++){
treeNode<int> child = takeInput();
root.children.push_back(child);
}
return root;
}
void printTree(treeNode<int> root){
cout<<root.data<<": ";
for(int i=0;i<root.children.size();i++){
cout<<root.children[i].data<<",";
}
cout<<endl;
for(int i=0; i<root.children.size();i++){
printTree(root.children[i]);
}
}
int main(){
treeNode<int> root= takeInput();
printTree(root);
return 0;
}
Following code is using dynamic allocation:
#include<bits/stdc++.h>
using namespace std;
template <typename T>
class TreeNode{
public:
T data;
vector <TreeNode<T>*> children;
TreeNode(T data){
this->data=data;
}
};
TreeNode<int>* takeInput(){
int rootdata;
cout<<"Enter node"<<endl;
cin>>rootdata;
TreeNode<int>* root=new TreeNode<int>(rootdata);
cout<<"Enter number of children of "<<rootdata<<endl;
int n;
cin>>n;
for(int i=0;i<n;i++){
TreeNode<int>* child=takeInput();
root->children.push_back(child);
}
return root;
}
void printTree(TreeNode<int>* root){
if (root == NULL){
return;
}
cout<< root->data<<" :";
for(int i=0;i<root->children.size(); i++){
cout<<root->children[i]->data<<",";
}
cout<<endl;
for(int i=0;i<(*root).children.size();i++){
printTree(root->children[i]);
}
}
int main(){
TreeNode<int>* root = takeInput();
printTree(root);
return 0;
}
Your code is equivalent to
A foo() {
A a;
a = bar();
return a;
}
a is just copied into the return value (That copy might be avoided too). Replace A with treeNode<int> and the semantics remain the same.
Why then the dynamic code?
I'm guessing the code version using dynamic allocation was probably coded up thinking that something like
struct A {
std::vector<A> vecA;
};
is a recursive definition for A since when vecA is declared A is an incomplete type. But that's not the case anymore and this is officially into C++17 (though it worked for some compilers in earlier versions too) where some STL containers can do with incomplete type. Hence it used the form
vector <TreeNode<T>*> children;
storing pointers to the children and hence that code, which is similar to the familiar LinkedList Node data structure definition
struct Node {
int data;
Node* next; // The TreeNode stores a vector of pointers instead.
};
Conclusion
Stack allocation is usually preferred when possible since it's faster than the heap route. Also, that code with dynamic allocation brings in the headache of memory management unless smart pointers are being used. It's just not needed for your code. Go with the stack allocation route for your example and let std::vector take care of maintaining the dynamic array.

Why is my linked list deleting after a function call?

In the code below I attempt to create a linked list of strings. I then use the linked list to store output generated by a function (named myFunction) which calls itself recursively. When testing/debugging the code, I noticed that if I print the contents of the linked list after executing the function (which should add items to the linked list) nothing prints out. However, if I attempt to print the linked list after adding items from inside the function it works fine.
It appears that the entire linked list is deleted after the call to myFunction. On the other hand, I'm using dynamic memory allocation when I add elements to the linked list so I don't see the issue.
Please help!
#include <cstdlib>
#include <iostream>
template <class T>
class node{
public:
node *next;
T data;
node(){next=0;};
void print();
};
template <class T>
void node<T>::print(){
std::cout << data;
}
template <class T>
class List{
public:
node<T> *head;
List(){head=0;};
void add(T data);
void print();
int len();
};
template <class T>
int List<T>::len(){
int i=0;
node<T> *current=head;
while(current!= 0){
i++;
current=current->next;
}
return i;
};
template <class T>
void List<T>::add(T myData){
node<T> *current=head;
if(head==0){
head= new node<T>;
head->data=myData;
}
else{
while(current->next!=0){
current=current->next;
}
current->next = new node<T>;
current->next->data=myData;
}
}
template <class T>
void List<T>::print(void){
node<T> *current=head;
if(head==0){
return;
}
else{
do{
std::cout << current->data << " ";
current=current->next;
}while(current!=0);
}
}
void myFunction(List<std::string> myList, int n, std::string starter, int leftParens, int rightParens){
int remainingLength = leftParens+rightParens;
if(remainingLength==0){
myList.add(starter);
std::cout <<myList.len() << std::endl;
}
if(leftParens >0){
myFunction(myList, n, starter+"(", leftParens-1, rightParens);
}
if(leftParens==0 and rightParens >0){
myFunction(myList, n, starter+")", leftParens, rightParens-1);
}
}
int main(int argc, char** argv) {
List<std::string> myList;
myFunction(myList, 5, "", 5, 5);
std::cout <<myList.len();
}
You are passing myList to myFunction by value. Any changes made to myList in the function are changes to the copy, not the original myList in main.
Change myFunction so that it accepts its argument by reference. Then, any changes made to it in myFunction will also be visible in main.
void myFunction(List<std::string>& myList, int n,
// ^^
std::string starter, int leftParens, int rightParens){
You need to use reference if you want to update the variable in the caller context (in other words, if you want to change the variable in main).
Whenever a class allocates memory, you probably need to follow the "rule of three" (constructor, copy-constructor, copy-assignment operator). If you don't, you'll get into trouble if you ever make a copy of the original class [like your call to myFunction as it currently stands]

stack is being reset after each push and shows empty message

i have a program with 3classes.
first one is for defining a node(my node is an array with 9 elements) - 2nd one contains some functions - 3rd is defining a static stack(I have a stack with 100members that each member is an array with 9members)
suppose that in main(), I call one of the functions from 2nd class(for example expand() ). expand function is supposed to push a node into stack(push into UN) and update the stack pointer. After that for example I want to have access to top node of stack and pop that node using main(). but I'm successful. when I watch the UN and top node through debug tool, I see that their amount is being reset after each push(stack doesn't accept new elements). whats wrong?
here is some parts of code that is needed:
#include<iostream>
using namespace std;
#define max 100
class node
{
public:
int node_n[9];
friend class func;
friend class stack;
};
node n;
class node;
class func
{
public:
func();
void expand(node,stack);
friend class stack;
};
class node;
class stack
{
private:
int sp;//stack pointer
public:
node un[max];//saves expanded noded(children)
stack();
int isempty(); //this will show whether stack is empty or not
int isfull(); //this will show whether stack is full or not
void push(node);
node pop();
};
//****************************
stack::stack()
{
sp=-1;
}
//****************************
int stack::isempty()
{
if(sp==-1)
return true;
else
return false;
}
//****************************
int stack::isfull()
{
return sp==max-1;
}
//****************************
node stack::pop() //un=un-[n]
{
for(int k=0;k<=8;k++)
n.node[k]=un[sp].node[k];
sp--;
return n;
}
//****************************
void stack::push(node n ) //un=un+{x1....xn}
{
sp++;
for(int k=0;k<=8;k++)
un[sp].node[k]=n.node[k];
}
//****************************
void func::expand(node n,stack st)
{
if ( n.node_n[0]==0 )
{
if(n.node_n[1]==0)
{
n.node_n[0]=1;
n.node_n[1]=1;
st.push(n);
.
.
.
//******************************
int main()
{
func b;
stack st;
node n2;
node s; //initial state
node g; //goal state
for(int h=0;h<=8;h++)
{
s.node[h]=0;
g.node[h]=1;
}
//n2=s;
st.push(s);
Lable1:
n2=st.pop();
b.expand(n2,st);
goto Lable1;
system("pause");
return(0);
}
This function
void func::expand(node n,stack st)
is taking the st parameter by value, meaning that it has its own copy of st and any changes it makes will only affect that copy.
What you probably want is to pass st by reference, so that the function can make changes to the original passed in object. To do this, change the function declaration and definition to:
void func::expand(node n,stack &st)

C++ How may I return an array class member of a nested class?

This is not a real question, since I've already solved the problem myself, but I still need some clarifications about the mechanism behind assigning an array's address to a pointer of the same type when the array is a class member of a nested class.
The following code is fully functioning, although it may lack some error_check. It is only meant to show how I made my (real) program work.
HEADER (linkedList)
class linkedList
{
public:
linkedList();
~linkedList();
int* getArray();
void forward();
private:
class listNode
{
public:
listNode();
~listNode();
friend class linkedList;
private:
int array[3];
listNode* next;
};
listNode *first;
listNode *current;
};
CPP (linkedList)
linkedList::linkedList()
{
first = new listNode;
current = first;
}
//~~~~~~~~~~~~
linkedList::~linkedList()
{
delete first;
first = 0;
current = 0;
}
//~~~~~~~~~~~~
int* linkedList::getArray()
{
if (current)
{
return &(current->array[0]);
}
}
//~~~~~~~~~~~~
void linkedList::forward()
{
if (current->next)
{
current = current->next;
}
}
//-------------------------
//-------------------------
//-------------------------
linkedList::listNode::listNode()
{
next = 0;
for (int i = 0; i < 3; i++){array[i]=((i+1)*3);}
}
//~~~~~~~~~~~~
linkedList::listNode::~listNode()
{
}
CPP (main)
#include <iostream>
#include "linked_list.h"
using namespace std;
int main()
{
linkedList list;
int *myArray;
myArray = list.getArray();
for (int i = 0; i < 3; i++){cout << myArray[i] << " ";}/**/cout << "\n\n";
return 0;
}
The real program is meant to move through a linked list made of nodes which contain 3 integer values in an array of int type, retrieve the three values and use them as parameters for some other functions.
Now, to do so I have to return the address to the first element of the array contained in the node through an accessor.
Apparently, the only way to do it is by returning the reference to the first element of the array in the node to which the linkedList's member variable current points to:
return &(current->array[0]);.
Why?
I've got to this solution through trial and error with very little knowlegde of the reasons that brought me to build this expression as it is.
Usually, when you want to assign the address of an array to a pointer, you just do so:
int main()
{
int array[3];
int* pArray;
pArray = array;
}
And that's it, because the name of the array itself is enough to retrieve the address of its first element.
The exact same result can be achieved by doing this (tested):
int main()
{
int array[3];
int* pArray;
pArray = &(array[0]);
}
Both methods are also valid when the accessor returns the address from a member variable of its own class.
But why, when accessing the member variable of a nested class, I'm forced to use the second method?
What are the logic stages that make it the only viable method?
But why, when accessing the member variable of a nested class, I'm forced to use the second method?
You aren't:
return current->array;
and
return &(current->array[0]);
Both do the same thing when the return type is int*. You aren't forced to use the second way.
Also, there's a bug in getArray. You don't return anything if current is null.
To be pedantic...
Apparently, the only way to do it is by returning the reference to the first element of the array in the node to which the linkedList's member variable current points to:
return &(current->array[0]);.
You're returning the address i.e. a pointer. Reference means something else.

c++ pointer reference confusion

struct leaf
{
int data;
leaf *l;
leaf *r;
};
struct leaf *p;
void tree::findparent(int n,int &found,leaf *&parent)
This is piece of code of BST. I want to ask. why
leaf *&parent
Why we need "reference mark" here?
parent is also a leaf, why can't I just use leaf* parent?
code below for your reference. Thank you!
void tree::findparent(int n,int &found,leaf *&parent)
{
leaf *q;
found=NO;
parent=NULL;
if(p==NULL)
return;
q=p;
while(q!=NULL)
{
if(q->data==n)
{
found=YES;
return;
}
if(q->data>n)
{
parent=q;
q=q->l;
}
else
{
parent=q;
q=q->r;
}
}
}
You are passing the pointer parent in by reference, so that you can modify that pointer:
parent=q;
If you passed the pointer in by value, the modifications would be to a copy of the pointer that expires at the end of the function.
When you use REFERENCE TO POINTER, you can change the value of the pointer. You may need to use this schema in link list implementation to change the head of the list.
void passPointer(int *variable)
{
*variable = (*variable)*2;
variable = NULL; // THIS CHANGES THE LOCAL COPY NOT THE ACTUAL POINTER
}
void passPointerReference(int* &variable)
{
*variable = (*variable)*3;
variable = NULL; // THIS CHANGES THE ACTUAL POINTER!!!!
}
int main()
{
int *pointer;
pointer = new int;
*pointer = 5;
passPointer(pointer);
cout << *pointer; // PRINTS 10
passPointerReference(pointer);
cout << *pointer; // GIVES ERROR BECAUSE VALUE OF pointer IS NOW 0.
// The constant NULL is actually the number 0.
}