Stack push using external function - c++

I'm trying to implement stacks using constructors in C++. I'm required to use an external function to push an element on the stack, however, it doesn't seem to work properly. The pushexternal function seems to "enter" the push function, but it doesn't increase the ind value, therefore it doesn't add a new element onto the stack (for example in my code, all pushxternals will try to push a value onto the same index, the last one used by s.push - ind==2). I'm not sure what I'm doing wrong.
Oh, I'm only supposed to modify the class code - the pushexternal and main have to remain unchanged.
#include <iostream>
using namespace std;
class Stack {
public:
int ind;
int * arr;
Stack()
{
arr = new int[25];
ind = -1;
}
~Stack()
{
delete [] arr;
}
void push(int val)
{
arr[++ind] = val;
cout << "Added " << arr[ind] << " to " << ind << endl;
}
void top()
{
cout << "Last: " << arr[ind];
}
};
void pushexternal(Stack s, int a) {
s.push(a);
}
int main() {
Stack s;
s.push(0);
s.push(1);
s.push(2);
pushexternal(s, 3);
pushexternal(s, 4);
pushexternal(s, 5);
return 0;
}
Results:
Added 0 to 0
Added 1 to 1
Added 2 to 2
Added 3 to 3
Added 4 to 3
Added 5 to 3
Top: 2

void pushexternal(Stack s, int a) {
s.push(a);
}
receives a Stack as a parameter, which means it receives an object which is a copy of your object.
You should operate on references, this way you will not send a copy of the object to be manipulated, but the reference of the object, thus the original object will be manipulated.

void pushexternal(Stack s, int a) {
s.push(a);
}
You are passing the Stack object to this function by value, not by reference. This makes a temporary copy of the original Stack object, so the original object remains unchanged. Not to mention that this will result in memory corruption, since the RAII principle has been violated.
Just by the luck of the draw, I guess, your code is not segfaulting.

Related

Can anybody explain me why this code is not working?

I'm learning C++. Now, I'm trying to make one sample related with overloading operators of an object. My object (called Contador) has different methods and variables which help user to count iterations.
Header file of the object:
class Contador
{
private:
int* Valor;
int* Salto;
public:
Contador(int Valor_Inicio = 0, int Salto = 1);
~Contador();
inline int Get_Valor() const { return *Valor; }
inline int Get_Salto() const { return *Salto; }
inline void Incremento() { Set_Valor(Get_Valor() + Get_Salto()); }
inline void operator++ () { Set_Valor(Get_Valor() + Get_Salto()); }
void Set_Valor(int Valor);
void Set_Salto(int Salto);
};
Cpp file of the object:
// Librerias Propias
#include "Contador.h"
Contador::Contador(int Valor_Inicio, int Salto)
{
Set_Valor(Valor_Inicio);
Set_Salto(Salto);
}
Contador::~Contador()
{
delete Contador::Valor;
delete Contador::Salto;
}
void Contador::Set_Valor(int Valor)
{
delete Contador::Valor;
Contador::Valor = new int(Valor);
}
void Contador::Set_Salto(int Salto)
{
delete Contador::Salto;
Contador::Salto = new int(Salto);
}
The main() function of the sample has 2 different for loops. In the first one, I call Incremento() method and in the second one I call the overloaded operator.
Main function:
void main()
{
// Genero el elemento de analisis.
Contador* contador = new Contador();
// Realizo el bucle con la funciĆ³n de incremento.
std::cout << "Incremento()" << std::endl;
for (contador->Set_Valor(0); contador->Get_Valor() < 3; contador->Incremento())
{
// Escribo algo.
std::cout << "Iteracion actual: " << contador->Get_Valor() << std::endl;
}
// Realizo el bucle on el operador sobrecargado
std::cout << "operador sobrecargado" << std::endl;
for (contador->Set_Valor(0); contador->Get_Valor() < 3; contador++)
{
// Escribo algo.
std::cout << "Iteracion actual: " << contador->Get_Valor() << std::endl;
}
}
The problem appears when main function passes the first iteration of the second loop. It throws one exception in Get_Valor() method.
It seems to me that it change the memory addres of the pointer Valorin some place, but I can`t find where.
Can anybody help me?
Thanks.
contador++ does not do what you think it does - contador is a pointer, not a Contador, so it will make contador point to something that does not exist.
You need to dereference the pointer.
However, *contador++ also increments contador - it is *(contador++) - and (*contador)++ does not compile because you have only overloaded the prefix operator (the postfix operator has the prototype operator++(int).
So, ++*contador will do what you want.
You can avoid many similar problems, and the clunky syntax, by not using pointers unnecessarily.
The expression contador++ increments the address that contador (a pointer) points to! So, after the first iteration, the pointer will be completely invalid.
To call the increment operator, you need: ++(*contador) which first dereferences the pointer to the object pointed to, then effects that object's increment operator.
3 coding issues:
main shoudl return int.
Valor and Salto are not initialized in constructor.
Contador::Set_Valor and Contador::Set_Salto requires initialized pointers (as you delete them).
Easy fix is:
class Contador
{
private:
int* Valor = nullptr;
int* Salto = nullptr;
//...
};
Last issue is in your last loop:
for (contador->Set_Valor(0); contador->Get_Valor() < 3; contador++)
As condator is a pointer (not pointing on an array), accessing condator[1] would be UB.
You wanted ++(*condator) (operator++ () is pre-increment whereas operator++ (int) is post-increment).
Finally, avoiding usage of all those pointers would simplify code (and no bother with rule of 3 you break):
class Contador
{
private:
int Valor;
int Salto;
public:
Contador(int Valor = 0, int Salto = 1) : Valor(Valor), Salto(Salto) {}
~Contador() = default;
int Get_Valor() const { return Valor; }
int Get_Salto() const { return Salto; }
void Incremento() { Set_Valor(Get_Valor() + Get_Salto()); }
void operator++ () { Set_Valor(Get_Valor() + Get_Salto()); }
void Set_Valor(int Valor) { this->Valor = Valor;}
void Set_Salto(int Salto) { this->Salto = Salto;}
};
int main()
{
Contador contador;
std::cout << "Incremento()" << std::endl;
for (contador.Set_Valor(0); contador.Get_Valor() < 3; contador.Incremento())
{
std::cout << "Iteracion actual: " << contador.Get_Valor() << std::endl;
}
std::cout << "operador sobrecargado" << std::endl;
for (contador.Set_Valor(0); contador.Get_Valor() < 3; ++contador)
{
std::cout << "Iteracion actual: " << contador.Get_Valor() << std::endl;
}
}
In addition to previous answers.
As I could see Contador* contador = new Contador(); code also contains UB (undefined behaviour)
This call is equal to constructor with parameters Contador(0, 1)
which will do Set_Valor and Set_Salto which call delete first but at this moment content of this variables is not guaranteed to be nullptr so you might corrupt data. Also compiler if it sees UB might optimize out all other code since it's already UB and it can change behaviour anyway it wants for example throw it away completely. https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633

Why is the static array member variable showing nothing after calling the instance of the object?

Currently working on Object Oriented Programming in c++ and having problems with an instance showing nothing changed from a method I've created.
The whole code is based off of this object I've created from a header file.
#ifndef DEQUE_H_
#define DEQUE_H_
#include <iostream>
const int CAPACITY = 5;
const int DEFAULT = -1;
class Deque
{
public:
Deque();
int get_size() const;
bool is_empty() const;
bool is_full() const;
int operator[](int i) const;
static Deque insert_tail(int);
private:
int size_;
static int array_[CAPACITY];
};
std::ostream & operator<<(std::ostream &, const Deque &);
#endif
One of the problems I'm having is the insert_tail method that doesn't show any changes to my static array.
In the cpp file itself.. these are the function declarations.
#
include <iostream>
#include "Deque.h"
Deque::Deque()
:size_(0)
{
}
int Deque::array_[5] = {};
int Deque::get_size() const
{
return size_;
}
bool Deque::is_full() const
{
if (size_ == 5) return 1;
else return 0;
}
bool Deque::is_empty() const
{
if (size_!= 5) return 1;
else return 0;
}
int Deque::operator[](int i) const
{
int something = array_[i];
return something;
}
Deque Deque::insert_tail(int x)
{
Deque d;
d.size_ += 1;
int size = d.size_;
d.array_[size - 1] = x;
return d;
}
std::ostream & operator<<(std::ostream & cout, const Deque & dq)
{
cout << dq.get_size() << " [ ";
for (int i = 0; i < dq.get_size(); ++i)
{
cout << dq[i] << " ";
}
cout << "]";
return cout;
}
The operator works just fine. The bools work just fine and the remove_head and remove_tail thing I'll do once I figure out insert tail. Right now, it's not making any chances to the very object I've created inside the main.
#include <iostream>
#include "Deque.h"
void print(const Deque & deque)
{
static int i = 1;
std::cout << i << ". " << deque << ", empty: " << deque.is_empty()
<< ", full: " << deque.is_full();
i++;
}
void test_insert_tail(Deque & deque, int x)
{
deque.insert_tail(x);
print(deque); std::cout << "\n";
}
int main()
{
Deque deque;
print(deque);
std::cout << "\n";
test_insert_tail(deque, 2);
return 0;
}
The output should look like this,
1. 1 [ 2 ], empty: 0, full: 0
but looks like this
1. 0 [], empty: 1, full: 0
What's going on inside my static method for handling all the private attributes that I'm missing on? What did I do wrong exactly?
The problem with your code is the misuse of the static word. In fact, static means that is not associated with an instance of the object: this means that the content of the static member (the array_ variable in this case) is shared between every instance you will create.
That's the same for the insert_tail method, that can be used even if you don't create an instance. Now, let's try to understand what you've written in this method:
Deque d;
d.size_ += 1;
int size = d.size_;
d.array_[size - 1] = x;
return d;
In the first line, you created a new Deque object. That's the first mistake, cause you're not modifying the actual Deque. Then you add the operations, and in the end, you return the created Deque. However, this object is not saved anywhere, because when you call deque.insert_tail() you aren't assigning the returned value anywhere.
Let's try and get this a little bit more concrete.
Since what you're doing is creating a data structure, you won't need any static member. This because everything needs to be saved inside the data structure.
Then, inside the insert_tail you'll need to remove the object you created inside. It'll look something like this:
size_ += 1;
int size = size_;
array_[size - 1] = x;
With those two modifications the code will probably work as expected, however, I suggest you focus on improving the appearance of your code. Using the underscore character at the end of the variable name is a little bit confusing. In C the only scenario you can use it inside the name int foo_bar for normal variables, and at the beginning int _foo for reserved variables.

push object in the heap using pointer to the static container

class Node_Str{
public:
string name;
string value;
string type;
Node_Str(string name,string value,string type){
name=name;
value=value;
type=type;}};
static stack<Node_Str> s;
void find_token(string input){
int cursor=0;
string current="";
while(cursor<input.length()){
char value;
value=input[cursor];
cout<<value<<endl;
if(value=='('||value==')'||value=='+'||value=='-
'||value=='*'||value=='/'){
Node_Str* p=new Node_Str("pare",string(1,value),"Pare");
s.push(*p);
cursor++;
delete p;}
if(value==' '){
cursor++;
}
if(value=='1'||value=='2'||value=='3'||value=='4'){
Node_Str* p=new Node_Str("num",string(1,value),"Number");
s.push(*p);
cursor++;
delete p;}}}
int main(){
while(!s.empty()){
cout<<s.top().value<<" ";
s.pop(); }
return 0; }
The find_token function should separate the input string by white Space and constructing the Node_Str object with the value of that string. Then in the
main function, I would like to print it. The characters are limit. Just '1', '2','3','4','+,'-','*','/'.
Input is 4 + 4 , output should be 4+4. However, there is no output.
The comments already said about memory leak and forgetting to call find.
In addition to that, stack is a container in which to last to be pushed in would be the first to be popped out. In order to output 0 1 2 3, you would need to push in the stack in the sequence of 3 2 1 0.
Just giving a better version.
#include <iostream>
#include <stack>
using std::cout;
using std::stack;
static stack<int> s;
void find()
{
int* p;
for (int i = 3; i >= 0; i--) {
p = new int(i);
s.push(*p);
delete p; // p itself does not have to be returned so it can be safely deleted here
//This can also ne replaced by directly using s.push(i)
}
}
int main() {
find();
while (!s.empty())
{
cout << s.top() << " ";
s.pop();
}
return 0;
}
as suggested by leyanpan, data should be pushed into reverse order, to get the desired output. One more point is no need of dynamic allocation for int type. It is always better to store non array built in types in stack rather than heap.
Also allocating stack data structure as static variable will extend scope up to program termination. Better to use stack object as a local variable in main and pass it as are reference argument to function find.

mergesort not working in c++

Is there anything wrong with the usage of the "return" values of the three fuction? The values printed out are garbage values with seemingly random numbers as outputs.I would also like to add that i havent made it recursive because i wanted to check whether this would work or not.
Most all of the mergesort implementation I've seen hardly contain any return values, is that something im doing wrong. If you were to go about a similar type of implementation, how would you do it?
#include <iostream>
using namespace std;
int* goleft(int array[], int size)
{
int halved=size/2;
int left[halved];
for(int i=0;i<halved;i++)
{
left[i]=array[i];
}
return left;
}
int* goright(int array[],int size)
{
int halved=size/2;
int right[size-halved];
for(int i=halved,j=0;i<size;i++,j++)
{
right[j]=array[i];
}
return right;
}
int* mergesort(int array[],int size)
{
int *l,*r;
l=goleft(array,size);
r=goright(array,size);
int merger[size];
int halved = size/2;
int i;
for(i=0;i<halved;i++)
cout<<l[i]<<endl;
for(i=0;i<halved;i++)
cout<<r[i]<<endl;
int x=0,y=0,k=0;
while(x+y!=size)
{
if(l[x]<r[y])
{
merger[k]=l[x];
x++;k++;
}
else if(l[x]>=r[y])
{
merger[k]=r[y];
y++;k++;
}
}
return merger;
}
int main()
{
int size;
cin>>size;
int array[size];
for(int i=0;i<size;i++)
cin>>array[i];
int *merged=mergesort(array,size);
cout<<"sorted array"<<endl;
for(int i=0;i<size;i++)
cout<<merged[i]<<endl;
return 0;
}
And when we create variables of same name during loops and recursions, are new variable created for every loop iteration or recursion? or do they overwrite the value for the previous variable. for e.g when we write
while(true)
{
int i=0;
}
would a new variable be made at every iteration
and
genericFunction()
{
int i = SomeRandomValue
genericFunction();
}
similarly would a new variable be made at each recursion?
As you thought, the error is in "scopes". To answer to your questions :
while(true)
{
int i=0;
}
The process is :
//iteration N start
create scope
allocate memory for an int variable named 'i' in the current scope
//statements done
delete current scope //deallocate the variables in the current scope
//iteration N end
//iteration N+1 start
/*...*/
So in each iteration it is a different variable. You can test it with this code :
while (true) {
int i;
std::cout << &i << std::endl; //displays the memory location of i
system("PAUSE"); //waiting user input between each iteration
}
In the example with genericfunction, the process is :
//N call to genericFunction
create scope //scope N
//N+1 call to generic Function
create scope //scope N+1
/* statements */
delete current scope //scope N+1
// exit of call N+1
delete current scope //scope N
//exit of call N
You can test it with this complete code :
#include <iostream>
void genericFunction(int a)
{
int i = 0;
std::cout << "scope " << a << " : " << &i << std::endl;
if (a < 9) { //to prevent infinite call
genericFunction(a + 1);
}
std::cout << "scope " << a << " : " << &i << std::endl;
}
int main() {
genericFunction(0);
system("PAUSE");
return 0;
}
A generic rule is : when you have {, you create a new scope and select it as current scope, when you have }, you delete the current scope and select the previous scope. Some scopes permits access to previous scopes (for example a WHILE LOOP : in the code int a; while(true) {a++;}, it modifies the value of a in the previous scope), but when a function scope is created you have no access to previous scopes.
Now for your specific issue with mergedsort, it is the declaration of your variable merger inside the function mergesort. To see the process :
/* ... */
int *merged=mergesort(array,size);
//Call to mergesort
//Creation of scope A
/* ... */
int merger[size]; //Allocation of memory for 'merger' in scope A
/* ... */
return merger; //Affect the location of 'merger' to location pointed by 'merged' in previous scope
//Deletion of scope A (including deallocation of 'merger')
// Now 'merged' points to location of 'merger' which is a deallocated variable :
//no guarantees of the data stored at this location
So it is why there is a problem in your code. One way to correct it is by allocate manually some space for your variable : variables allocated manually have to be deallocated manually, so they will not be deallocated when destroying a scope. Actually the implementation inside the function is using the c++ keyword new : int *merger = new int[size];.
By replacing this declaration your code will be running : but be careful : here's an other rule, if you're using somewhere the keyword new you have to use delete somewhere else : manual allocation have to be followed by manual deallocation. So at the end of your main function, you have to add delete[] merged;. In this way there's no trouble ;) .

Class creating multiple objects of another class at the same memory location (C++)

So, I've got this class that contains a vector of another class. Whenever I try to push a new object into this vector, it's creating that object at the same memory location each time.
The (hopefully) relevant code:
class FSM{
private:
std::vector<Node> nodeList;
int cap;
int obs;
int topNode;
public:
FSM(int nodeCap, int numObs){
cap = nodeCap;
obs = numObs;
topNode = -1;
}
bool addNode(){
if (isFull()) return false;
nodeList.push_back(Node(obs));
topNode++;
return true;
}
Now, if I create a stand-alone Node object in my main function and cout the &node, I get different memory locations. But the ones created in the FSM class are always the same. Also, if I change anything in one of the Nodes stored by the FSM class, it changes it for all of them. I have no idea what's going on.
EDIT: As requested, here is the Node class. Just gonna post the whole thing, not sure what is relevant.
class Node{
private:
std::vector<int> connects;
int action;
public:
Node(int numObs){
for(int i = 0; i < numObs; i++){
connects.push_back(-1);
}
srand(time(NULL));
}
void setConnections(std::vector<int> newVec){
for (int i = 0; i < connects.size(); i++){
connects[i] = newVec[i];
}
}
int getConnection(int index){
return connects[index];
}
std::vector<int> getConnectionList(){
return connects;
}
void setAction(int act){
action = act;
}
int getAction(){
return action;
}
void setRandomConnections(int numNodes){
for (int i = 0; i < connects.size(); i++){
connects[i] = rand() % numNodes;
}
}
};
EDIT the Second: Here's what my main is doing.
int main(){
FSM myFSM(5, 3);
while (!myFSM.isFull()){
myFSM.addNode();
std::cout << &myFSM.getTopNode(); // getTopNode() returns the most recent
// node.
}
}
If getTopNode does what I think it does, you're printing the address of a temporary object (aka a copy of the top node, not the top node itself). So that code is meaningless.
Here I've implemented a print function for the locations of the nodes in FSM:
void printNodeLocations()
{
for(Node& n : nodeList) { std::cout << &n << std::endl; }
}
And I get different ones as expected:
0x8ad3018
0x8ad301c
EDIT: I cannot reproduce your claim that changing one node changes all of them. See updated code
This line:
std::cout << &myFSM.getTopNode();
probably prints the address of a temporary object, not the actual object in the vector. This will be true if you're not returning by reference but rather by value.
So it's not weird if the temporary happens to be created at the same location each time, since after the temporary dies, its location in memory is free to be used again later.
In order to get the actual object rather than a copy of it, getTopNode() needs to do:
Node& FSM::getTopNode()
{
if (nodeList.empty()) {
// Up to you how to handle this error.
}
return nodeList.back();
}
Of course, if your current getTopNode() implementation actually already returns a pointer:
Node* FSM::getTopNode()
then your problem is that you're printing out the address of the pointer rather than the pointer itself. In that case you should print with:
std::cout << myFSM.getTopNode();
Nothing happens similar to yours.
#include <iostream>
#include <vector>
class Node{
private:
std::vector<int> connects;
int action;
public:
Node(int num){
for(int i = 0; i < num; i++){
connects.push_back(i);
}
}
std::vector<int> getConn()
{
return connects;
}
};
class FSM{
private:
std::vector<Node> nodeList;
public:
FSM(){}
void addNode(int size){
Node l(size);
std::cout<<"temp_address "<<&l<<"\n";
nodeList.push_back(l);//use of default copy constructor
}
void printList(){
std::vector<int> p;
for (int i=0; i<nodeList.size(); i++)
{
std::cout<<"Node_arr_num "<<i<<" mem_address "<<&nodeList[i]<<"\nConnections:";
p=nodeList[i].getConn();
for (int j=0; j<p.size(); j++)
std::cout<<" "<<p[j];
std::cout<<"\n";
}
}
};
int main()
{
FSM f;
f.addNode(5);
f.addNode(10);
f.addNode(3);
f.printList();
return 0;
}
Result:
temp_address 0xbfea7660
temp_address 0xbfea7660
temp_address 0xbfea7660
Node_arr_num 0 mem_address 0x8dab098
Connections: 0 1 2 3 4
Node_arr_num 1 mem_address 0x8dab0a8
Connections: 0 1 2 3 4 5 6 7 8 9
Node_arr_num 2 mem_address 0x8dab0b8
Connections: 0 1 2
Be careful with adding nodes later, when your app will grow. Temporary l object (ore your Node(obs)) must be copied with explicit copy constructor of class Node if Node will be more complex (contains fields with dynamic allocated memory).