this is a simple program for using a stack. it basically does all the stack operations, when I run it the programming is not working for some reason and I can't figure out the reason why. also, is there any way I can improve this current code?
this is the program code here
//
#include <iostream>
using namespace std;
struct stack {
int top = -1;
int size;
int* p;
} *stack;
struct stack* createStack(int size)
{
struct stack st;
st.p = new int[size];
st.size = size;
struct stack* stackPointer = &st;
return stackPointer;
}
void push(struct stack* st, int el) {
if (st->top == (st->size) - 1) {
cout << "this operation cannot be done as the size is full :(" << endl;
}
else
{
st->top = (st->top)++;
st->p[st->top] = el;
}
}
void pop(struct stack* st) {
if (st->top == -1)
cout << "stack is already empty" << endl;
else
st->p[st->top] = NULL;
}
void displayStack(struct stack* st) {
for (int i = 0; i <= st->top; i++) {
cout << st->p[i] << endl;
}
}
int main()
{
struct stack* st = createStack(5);
push(st, 1);
push(st, 2);
push(st, 3);
push(st, 4);
displayStack(st);
pop(st);
displayStack(st);
}
There are a few problems with your code. First, as others have said, you're just doing C code without cout. Instead, you might want stack to look like this:
struct stack {
stack(int sz);
void push(int value);
int pop();
int top = -1;
int size = 0;
int * p = nullptr;
};
std::ostream & operator<<(stack &stack) {
for (int i = 0; i <= stack->top; i++) {
cout << stack->p[i] << endl;
}
}
stack::stack(int sz)
: size(sz), p(new int[size])
{
}
void push(int value) {
if (top == (size) - 1) {
cout << "this operation cannot be done as the size is full :(" << endl;
}
else {
p[++top] = el;
}
}
int pop() {
return top < 0 ? INT_MIN : p[top--];
}
int main() {
stack st(5);
st.push(1);
st.push(2);
st.push(3);
st.push(4);
cout << "First dump: " << st << endl;
st.pop();
cout << "Second dump: " << st << endl;
}
At first: You tagged C++, but your code is C – apart from not providing void to main, outputting to std::cout and using namespace std – the latter you shouldn't do anyway!
createStack function should be a constructor instead, push and pop should be member functions and you should prevent access to the internal data by making it private. Typically, one would rather use a class than a struct (structs usually are used for POD types). That would look like:
class Stack
{
// default accessibility for class is private, so need to switch to public first
public:
Stack(size_t capacity)
: m_capacity(capacity), m_size(0), m_data(new int[capacity])
{ }
bool push(int value);
bool pop();
int top();
// now private section:
private:
size_t m_capacity;
size_t m_size;
//int* m_data;
// use of a smart pointer avoids necessity to care for memory management manually:
std::unique_ptr<int[]> m_data;
};
Sure, that looks pretty different now. But that's the C++ way. If you don't get along with you might want to peek in a good C++ book.
Some additional changes:
I renamed size to capacity, and top to size. Correct data type for specifying object or array sizes is std::size_t (or just size_t), you need to #include <cstddef> for. Note, though, that this type is unsigned (negative sizes are meaningless anyway).
Old top/new size has different semantics, not indexing the last element, but holding the number of elements – or index to one past the last element. This is rather typical semantics in C++ – and actually C as well.
The m_ prefix signals the variables being members of a class, it helps distinguishing class members from local variables. Such a convention is not uncommon, but no necessity. Decide you yourself if you want to follow or not...
I added a top function returning the last element on the stack. Note that the data and size members are private, so they cannot be accessed from outside the class, thus a user couldn't retrieve the top element without the function.
I changed the return types from void to bool – it is a pretty questionable idea to do any output from within a general purpose class. Users of it might want to provide different output, e.g. in another language, and you now are spoiling their programme. In other words: You limit reusability. So let's just return a success indicator and leave the output to the user (you personally would do so within main then).
Of course implementation needs to be changed a little bit, too. You might add the function bodies directly within the class definition (drop the semicolon then), usually you define the class in a header (stack.h or stack.hpp), but the member functions in a separate source file (stack.cpp). The latter would then contain:
#include "stack.h" // should always be the very first include:
// implicit check, if the header is self-contained, i.e.
// includes all headers it needs for the class definition
bool stack::push(int value)
// ^^ scope resolution: identifies the push function of class stack
{
if(m_size == m_capacity)
{
return false;
}
m_data[m_size++] = value;
return true;
}
bool stack::pop()
{
if(m_size == 0)
{
return false;
}
--m_size;
// you don't need to assign another value like 0
// it would be overwritten with next push anyway
//
// note that NULL would have been wrong anyway, that's for pointers!
// apart from, you should prefer C++ KEYWORDS over obsolete C MACROS,
// i.e. prefer nullptr over NULL
//
// note, too, that you did NOT reduce top on popping in your version
// should have caused outputting 1234 twice in your test code instead
// of 1234 and 123 – which I assume you meant by 'not working'
// – please get used to more precise error descriptions, by the way!
return true;
}
int top()
{
return m_data[m_size - 1];
}
Well, top is a pretty basic implementation, it relies on undefined behaviour if the stack is empty (i.e. it is the responsibility of the user to check size first!). Alternatively you could:
check the size yourself and throw an exception if the stack is empty
change the return type to bool and have a reference argument to provide the top value to (bool top(int& value);) – as being a reference, you indeed can do assignments to.
main would contain code like this one:
Stack s;
s.push(1);
// ^ call class member function; for pointers use ->
s.push(2);
std::cout << s.top();
s.pop();
Finally outputting the entire stack:
Have you noticed that you can write std::cout << 7 << someVariable << std::endl;? What if you could do the same with your stack?
No problem:
class Stack
{
public:
// see above
private:
// need to declare a FRIEND so that the function/operator has access to
// the private class members
friend std::ostream& operator<<(std::ostream& s, Stack const& s);
// private members, see above
};
std::ostream& operator<<(std::ostream& s, Stack const& s)
{
// now do the output to s just as the original displayStack did to std::cout
// but consider the changed semantics of top/size
return s;
}
That's it:
Stack s;
std::cout << s << std::endl; // now fine
That's called operator overloading.
EDIT: Considering paddy's comment to the question (didn't notice myself):
Main reason for your original programme failing was returning a local variable from the stack. That variable runs out of scope on leaving the function, though, so accessing it is actually undefined behaviour. What then happens technically is that the stack's contents (top, size and the pointer) likely get overwritten by next function call that reuses the stack. A problem gone away with the new class + constructor approach proposed above...
Related
I have two data types, A and B and I have to store the A instance in B in order to refer the A instance in a B method. Both are instantiated in the main function, so the two variables would live for as long as the program is running.
I don't want to make copies, I want to use something like an old fashioned pointer but also I want to follow (and learn) the modern C++ best practices. So what is the most appropriate type to store the A instance in B? (and why?)
I thought that if I want to use a pointer, the best way with modern C++, is using smart pointers, but references seems easier and lighter, so what is the best practice to refer to a variable created in a scope (for example in the main function) and used in another scope (for example a method of a class that has a pointer to that variable), knowing that the scope where that variable is created lives for as long as the class exists (when the stack is deallocated, it will free both the variable and the object that has the variable reference)?
struct A {};
struct B {
A & a;
B(A & a) : a(a) {}
};
int main() {
A a{};
B b{a};
}
or
#include<memory>
struct A {};
struct B {
std::shared_ptr<A> a;
B(auto a) : a(a) {}
};
int main() {
B b{std::make_shared<A>()};
}
The program I'm making is essentially a bunch of test to learn SDL2, I published the repo here https://github.com/antcolag/prova-sdl, B is the App class and A is the EventHandler class instantiated inside the main function.
As #πάντα-ῥεῖ noticed in my particular case the only reasonable way is with smart pointer, because I'm trying to use std::thread and std::atomic, but in a most general case what is the best way to replace the old C style pointers, with a more modern approach, when a variable is allocated in the stack, used by some other object and then deallocated from the stack together with the object?
If i understood the problem, you want to move the instance to a different "owner", with A a; it is posible but it requires a memcpy() if the scope of the instance is deleted. The most easy solution is to contain it in a shared scope, that is bad because it can be a global scope, the next best thing is to pass the reference to the owner (the structure that contains the data). At the end this are cheap solutions if they are applied over and over, modern c++ has a lot of tools for memory control / flow; most of those are pointer based because the data pointer copy is trivial, note that only in combination with std::atomic or a similar lib is suitable for multithreading.
This example shows how a data pointer can be moved and used without any fancy c++, a small note on the pointer idea, in the example the pointer address is not changing as long as it is not deleted, any reference made will persist even if ref_objs order is changed, the data is "on the wild" and the pointer is a number.
#include <iostream>
struct Object {
int num = 69;
};
struct Container {
// Better to use std::vector but
// this shows better what it does
// Olso can be replaced with
// Object * ref_objs [n] if n is fixt
Object ** ref_objs;
uint32_t n_obj;
uint32_t n_obj_max;
void provision_for(uint32_t res_len){
// To initialize data is better to use
// use a method insted of the constructor;
// This alocates n spaces of obj pointers
ref_objs = new Object * [res_len];
n_obj_max = res_len;
n_obj = 0;
}
void clear_all(){
uint32_t i;
for (i=0; i < n_obj; i++){
delete ref_objs[i];
}
delete [] ref_objs;
n_obj = 0;
}
Object * add_obj(){
Object * ret = nullptr;
if (n_obj < n_obj_max){
ref_objs[n_obj] = new Object;
ret = ref_objs[n_obj];
n_obj++;
}
return ret;
}
void del_obj(uint32_t n){
if (n < n_obj - 1){
// keeps them alighned
ref_objs[n] = ref_objs[n_obj];
}
delete ref_objs[n_obj];
n_obj--;
}
int recive_obj(Object * ref){
int res = 1;
if (n_obj < n_obj_max){
ref_objs[n_obj] = ref;
n_obj++;
res = 0;
}
return res;
}
int transfer_to(Container * to, uint32_t item){
int res = 1;
if (to->recive_obj(ref_objs[item]) == 0){
if (item < n_obj - 1){
ref_objs[item] = ref_objs[n_obj - 1];
} else {
ref_objs[item] = nullptr;
}
n_obj --;
res = 0;
}
return res;
}
Object * at (uint32_t at){
return ref_objs[at];
}
Object & operator [](uint32_t at){
// [0] is added to asure the compiler that it
// is a instance and not an array
return ref_objs[at][0];
}
};
int main(void){
Container container_a;
Container container_b;
container_a.provision_for(10);
container_b.provision_for(15);
Object * x = container_a.add_obj();
Object * y = container_a.add_obj();
Object * z = container_b.add_obj();
std::cout << "container_a len -> " << container_a.n_obj << std::endl;
std::cout << "container_b len -> " << container_b.n_obj << std::endl;
y->num = 200;
container_a.transfer_to(&container_b, 0);
container_b[1].num = 400;
std::cout << "container_a obj[0].num -> " << container_a[0].num << std::endl;
std::cout << "container_b obj[0].num -> " << container_b[0].num << std::endl;
std::cout << "container_b obj[1].num -> " << container_b.ref_objs[1]->num << std::endl;
container_a.del_obj(0);
container_a.clear_all();
container_b.clear_all();
return 0;
}
(This example is template suitable, just change all Object with the typename and the instance will be Container<Object> container_a;)
I try to print values from my object class, but I am unable to properly access the information stored at the pointer. Below I have defined a simple struct.
When compiled, I get an error:
no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'std::vector<int>')
void PrintNode(Node *node) { cout << node->key << endl; }
struct Node
{
vector<int> key;
int parent;
Node(vector<int> x, int y){ key = x; parent = y; }
void PrintNode(Node* node) { cout << node->key << endl; }
};
I call my PrintNode in my BFS function:
void BFS( vector<int> permutation, int n ) {
vector<Node*>Pointers;
queue<Node*> Queue;
Node* start = new Node(permutation, -1);
Node::PrintNode( start );
Pointers.push_back( start );
}
I don't understand why I am unable to cout the integer vector stored in .key of the node object. I believe that I am dereferencing the pointer correctly with node->key.
The standard library doesn't support direct iostreams output of a vector. But you can easily define such an operation. Just do it with a loop.
std::cout cannot handle raw vectors, you must convert it to an array which is can process first. You can do this using vector's .data() method
Example:
void PrintNode(Node* node) { cout << node->key.data() << endl; }
I try to print values from my object class, but I am unable to properly access the information stored at the pointer. Below I have defined a simple struct.
The simple answer to this question is the fact that std::vector<type, allocator> does not have an overload for the std::ostream::<< operator. Hence when you try to print out the entire vector of keys, it won't work the way you expect it to. I have seen several answers on other posts which suggest overloading the << operator for std::vector but unless you know what you are doing I would avoid doing this for several reasons, one of them being global namespace pollution and the second being incorrect handling of the overloading itself.
Also, please stop doing using namespace std;. It will not help you in any way and just make things worse in the most unexpected ways.
Here are some fixes which may help.
Part 1 - Node struct
struct Node : public std::enable_shared_from_this<Node>
{
std::vector<int> keys;
int parent;
Node(vector<int> x, int y) : keys(x), parent(y){}
Node(const Node& rhs): keys(rhs.keys), parent(rhs.parent) {}
Node(Node&& rhs) noexcept: keys(std::move(rhs.keys)), parent(rhs.parent){}
void PrintNode()
{
for (auto& key : node->keys)
cout << key << "\n";
}
};
Part 2 BFS Code
void BFS(std::vector<int>& permutation, int n )
{
/* I don't see the real value in creating pointers for your case. You can easily live with an instance of the class Node. This also gives you scoped initialization as the pointers vector goes out of scope, your nodes will get deallocated too. at least in the context, you have posted above, that seems desirable.
However, if you insist on creating pointers, you can use smart pointers.
*/
std::vector<std::shared_ptr<Node>> pointers;
std::queue<std::shared_ptr<Node>> queue; // not used??
auto start = std::make_shared<Node>(permutation, -1); // make a shared pointer
/* PrintNode in your code is an instance level function. Invoke it using the scope resolution operators . or ->. If you insist on doing it your way, then declare the function static. However, that has its own quirks and you need to understand static functions before you do this. */
start->PrintNode();
pointers.push_back(std::move(start)); // add your pointer to the vector.
}
That said the code excerpt you have posted makes little sense. I have just provided fixes for the parts you have provided. Does not guarantee that it will work in the larger context you may have at hand.
I have a task to create an object Stos which would feature a heap of objects Obiekt, to which I could add things as I please.
In order to make the program better support dynamic arrays I decided to use a Vector.
The whole implementation seems to run perfectly, the returned value is completely off.
Here is an example with code:
class Obiekt {
private:
int id;
public:
Obiekt::Obiekt(int i) {
id = i;
}
void Obiekt::display() {
cout << "This object has id of: " << id << endl;
}
};
class Stos {
private:
vector < Obiekt* > stos;
public:
Stos::Stos(Obiekt n) {
add(n);
}
void Stos::add(Obiekt n) {
stos.push_back(&n);
}
void Stos::display() {
cout << endl << "===HEAP DISPLAY===" << endl;
for (int i = 0; i < stos.size(); i++) {
stos[i]->display();
}
}
};
void Zad1()
{
Obiekt obj1(5);
Obiekt obj2(23);
Stos s1(obj1);
s1.add(obj2);
s1.display();
getchar();
}
And the outcome being:
===HEAP DISPLAY===
This object has id of: -858993460
This object has id of:9805925
I'm not a cpp expert, and believe the issue is related to the stos.push_back(&n) portion, but I can't catch the moment the id gets so distorted.
It's probably a noob question, so sorry for that on start.
Any help would be amazing.
The issue with your code as O'Neil correctly explained is that you're adding the pointer to a copy of the Obiekt object. So basically, you create your object in main, and pass it to the constructor and the .add function in Stos. You then add the pointer to the vector. When the function finishes, the copy that was passed is destroyed and the pointer in your vector is dangling.
There are two ways to fix this:
1 Pass by reference
This is very simple, basically you just add an ampersand to your function parameters. For instance:
void Stos::add(Obiekt &n) {
stos.push_back(&n);
}
This will ensure that the object isn't destroyed at the end of the function
2 Don't use pointers
Another way of getting your problem to work is to avoid using pointers at all. Your vector will actually copy the contents of the Obiekt object into it. For example:
vector < Obiekt > stos; // notice how we define it without the pointer type
...
void Stos::add(Obiekt n) {
stos.push_back(n); // Creates copy which will then contain the correct value
}
The parameters Obiekt n in
Stos::Stos(Obiekt n) {
add(n);
}
void Stos::add(Obiekt n) {
stos.push_back(&n);
}
are temporary copies destroyed immediatly after each call.
You have to use a reference Obiekt & n instead, or better: by pointer Obiekt * n.
I'm reluctant to assert that the objects exist at the time display is called.
Problem(s)
According to GCC's implementation they don't.
They fall out of scope and are immediately destructed. Give "Obiekt" a non-trivial destructor and this behavior becomes obvious:
~Obiekt(){std::cout << "Bye from: " << it << std::endl;}
Secondarily, note that you shouldn't specify the class membership for functions defined within the class itself (no class_name::function_name(parameters), just function_name(parameters) )
Possible Fix
You (might) want to changing "Stos" such that:
Stos(Obiekt &n) {add(n);}
void add(Obiekt &n) {stos.push_back(&n);}
I'm trying to retrieve an item from a BST for an assignment in class. Some of the provided code I am not allowed to alter. The instructor has created a retrieve function in the driver (which I can't change) that looks like this
static void retrieveItem(char *name)
{
Data const *data;
cout << ">>> retrieve " << name << endl << endl;
if (database->retrieve(name, data))
cout << *data << endl;
else
cout << "not found" << endl;
cout << endl;
}
The function it calls in the BST class looks looks like this (so far). I cannot change the arguments to the function call.
bool BST::retrieve(const char *key, Data const *& data) const
{
int rIndex = 0;
while (rIndex <= capacity)
{
if (strcmp(items[rIndex].data.getName(), key) == 0)
{
data = items[rIndex].data;
return true;
}
else if (strcmp(items[rIndex].data.getName(), key) < 0)
rIndex = (rIndex * 2) + 1;
else if (strcmp(items[rIndex].data.getName(), key) > 0)
rIndex = (rIndex * 2) + 2;
}
return false;
}
There is an array of structs called items that looks like this
struct Item
{
Data data; // the data instance must be specified this way, NOT as a pointer
bool isEmpty = true;
int loc = 0;
};
Item *items;
Finally I have the following assignment overload and copy constructors implemented for the data class (can't change the source file on this one)
Data::Data(const Data& source)
{
strcpy(this->name, source.name);
}
Data& Data::operator=(const Data& data2)
{
strcpy(this->name, data2.name);
return *this;
}
Please correct me if I'm wrong, but it seems like the goal of his retrieve function in the driver is to search for a data object using a key(name), and then copy it into the data argument sent to function. Unfortunately, the line
data = items[rIndex].data;
in my retrieve function doesn't work with a . or an ->]
I'm 90% sure the . is the correct way to access that, but I'm given the error "no suitable conversion type from 'Data' to 'const Data *' exists"
How else could I achieve this without using the assignment overload operator, or my implementation of the overload wrong?
bool BST::retrieve(const char *key, Data const *& data) const
The second argument is a reference to a pointer to const Data, so you must set it to a pointer to items[rIndex].data, not to its value.
Consider the following
void foo(int & out)
{
out = 42;
}
When it is called like so
// ...
int x = 0;
foo(x);
std::cout << x;
42 will be printed, because a reference to x was passed into the function. Your situation is a little different - you are passed a reference to a pointer, so that the caller can retrieve a pointer to the data in a similar way to the above, for example:
int x; // global
// ...
void foo(int *& out)
{
x = 42;
out = &x; // set out to pointer to x
}
int main()
{
int * ptr = nullptr;
foo(ptr); // foo will set ptr to the pointer to x
std::cout << *ptr; // prints 42
}
Again, 42 will be printed. Note the use of the unary ref, &, and deref, *, operators to get a pointer to x and dereference ptr to extract its value.
As an aside, it's not possible to tell how broken your implementation of Data::operator= is without seeing more of the class. As it stands it is broken because it is undefined behaviour to use strcpy on overlapping regions of memory - which will happen if someone tries to assign an object instance to itself (see strcpy). For cases other than self-assignment, it is only correct if the destination of the assignment always has enough space for the string in the source. Otherwise you will write to unallocated memory. Also, if there are any additional member variables, they will need copying too.
Suppose I have a class like
class Empty{
Empty(int a){ cout << a; }
}
And then I invoke it using
int main(){
Empty(2);
return 0;
}
Will this cause any memory to be allocated on the stack for the creation of an "Empty" object? Obviously, the arguments need to be pushed onto the stack, but I don't want to incur any extra overhead. Basically I am using the constructor as a static member.
The reason I want to do this is because of templates. The actual code looks like
template <int which>
class FuncName{
template <class T>
FuncName(const T &value){
if(which == 1){
// specific behavior
}else if(which == 2){
// other specific behavior
}
}
};
which allows me to write something like
int main(){
int a = 1;
FuncName<1>(a);
}
so that I get to specialize one template parameter, while not having to specify the type of T. Also, I am hoping the compiler will optimize the other branches away inside the constructor. If anyone knows if this is true or how to check, that would be greatly appreciated. I assumed also that throwing templates into the situation does not change the "empty class" problem from above, is that right?
Quoting Stroustrup:
Why is the size of an empty class not zero?
To ensure that the addresses of two different objects will be different. For the same reason, "new" always returns pointers to distinct objects. Consider:
class Empty { };
void f()
{
Empty a, b;
if (&a == &b) cout << "impossible: report error to compiler supplier";
Empty* p1 = new Empty;
Empty* p2 = new Empty;
if (p1 == p2) cout << "impossible: report error to compiler supplier";
}
There is an interesting rule that says that an empty base class need not be represented by a separate byte:
struct X : Empty {
int a;
// ...
};
void f(X* p)
{
void* p1 = p;
void* p2 = &p->a;
if (p1 == p2) cout << "nice: good optimizer";
}
This optimization is safe and can be most useful. It allows a programmer to use empty classes to represent very simple concepts without overhead. Some current compilers provide this "empty base class optimization".
It might, it might, not, depending on circumstances. If you say:
Empty e;
Empty * ep = & e;
then obviously things have to be allocated.
Try it and see. Many compilers will eliminate such temporary objects when asked to optimise their output.
If the disassembly is too complex, then create two functions with different numbers of such objects and see if there is any difference in the stack locations of objects surrounding them, something like:
void empty1 ( int x )
{
using namespace std;
int a;
Empty e1 ( x );
int b;
cout << endl;
cout << "empty1" << endl;
cout << hex << int ( &x ) << " " << dec << ( &x - &a ) << endl;
cout << hex << int ( &a ) << " " << dec << ( &a - &b ) << endl;
}
and then try running that compared with an empty8 function with eight Empties created. With g++ on x86, if you do take the address of any of the empties you get a location between x and a on the stack, hence including x in the output. You can't assume that the storage for objects will end up in the same order as they are declared in the source code.