I have the following main program that creates a Stack object, fills it with doubles and then pops them. The code files fine, but the pop_back() part does not seem to work, while s.back() does return the correct value. How is this possible?
#include "Stack.h"
#include <iostream>
#include <deque>
using namespace std;
int main() {
Stack<double> s(0,0.0);
// Write doubles into Stack
int i ;
for (i=0 ; i<15 ; i++) {
s.push(i*i) ;
}
// Read doubles back from fifo
while (!s.empty()) {
double val = s.pop() ;
std::cout << "Popping value " << val << " from stack" << std::endl ;
}
return 0 ;
}
My header file looks like this, where I have omitted parts which are not relevant to the question.
#ifndef STACK_H
#define STACK_H
#include <iostream>
#include <deque>
template<class T>
class Stack {
public:
Stack(int len, T defval): s(len+1, defval) {
return;
}
~Stack() {
//delete [] s;
}
void push(T c) {
s.push_back(c);
}
T pop() {
return s.back();
s.pop_back();
}
private:
std::deque<T> s; //Array<T> s;
};
#endif
T pop() {
return s.back();
// ^^^^^
s.pop_back(); // <- unreachable!
}
When you return from a function, all the subsequent instruction will never be executed.
Store s.back()'s result in a temporary variable instead:
T pop() {
auto back = s.back();
s.pop_back();
return back;
}
Related
I've got a vector of objects (apples) and I need a pointer to jump through every element, to print "size" value on every object in "apples". I tried vector::iterator, pointing whole vector but I still cannot get correct solution
#include <iostream>
#include <vector>
class Apple{
public:
int size;
Apple(int size): size(size){}
void print(){
std::cout<<size;
}
};
std::vector<Apple*>apples = {new Apple(21), new Apple(37), new Apple(66)};
Apple* ptr = apples[0];
void nextApple(){
ptr++;
ptr->print(); //returns 0
}
int main()
{
nextApple();
return 0;
}
Big thank You for any help!
To iterate through any T[] array using a pointer, you need to use a T* pointer, and you need to point it initially at the address of the 1st element, not the value of the element.
Your vector's element type is T = Apple*, not T = Apple, so you need to use an Apple** pointer rather than an Apple* pointer, eg:
#include <iostream>
#include <vector>
class Apple{
public:
int size;
Apple(int size) : size(size){}
void print(){
std::cout << size << std::endl;
}
};
std::vector<Apple*> apples = {new Apple(21), new Apple(37), new Apple(66)};
Apple** ptr = &apples[0];
void nextApple(){
++ptr;
(*ptr)->print();
}
int main()
{
nextApple();
return 0;
}
Using an iterator instead (or even an index) would have worked just fine, eg:
#include <iostream>
#include <vector>
class Apple{
public:
int size;
Apple(int size): size(size){}
void print(){
std::cout << size << std::endl;
}
};
std::vector<Apple*> apples = {new Apple(21), new Apple(37), new Apple(66)};
std::vector<Apple*>::iterator iter = apples.begin();
// or: size_t index = 0;
void nextApple(){
++iter;
(*iter)->print();
// or:
// ++index;
// apples[index]->print();
}
int main()
{
nextApple();
return 0;
}
That being said, using a vector of raw Apple* pointers is not a good idea. You have to delete the Apple objects when you are done using them. At the very least, you should wrap the pointers in std::unique_ptr to avoid memory leaks, eg:
#include <iostream>
#include <vector>
#include <memory>
class Apple{
public:
int size;
Apple(int size): size(size){}
void print(){
std::cout << size << std::endl;
}
};
std::vector<std::unique_ptr<Apple>> apples = {std::make_unique<Apple>(21), std::make_unique<Apple>(37), std::make_unique<Apple>(66)};
auto *ptr = &apples[0];
// or: auto iter = apples.begin();
// or: size_t index = 0;
void nextApple(){
++ptr;
(*ptr)->print();
// or:
// ++iter;
// (*iter)->print();
// or:
// ++index;
// apples[index]->print();
}
int main()
{
nextApple();
return 0;
}
But really, just get rid of the dynamic allocation altogther, you don't need it in this example:
#include <iostream>
#include <vector>
class Apple{
public:
int size;
Apple(int size): size(size){}
void print(){
std::cout << size << std::endl;
}
};
std::vector<Apple> apples = {21, 37, 66};
Apple* ptr = &apples[0];
// or: auto iter = apples.begin();
// or: size_t index = 0;
void nextApple(){
++ptr;
ptr->print();
// or:
// ++iter;
// iter->print();
// or:
// ++index;
// apples[index].print();
}
int main()
{
nextApple();
return 0;
}
The code in the question is not idiomatic C++; more like a Java design. In C++ iterators just work:
void show_apples() {
std::vector<Apple> apples =
{ Apple(21), Apple(37), Apple(66) };
for (auto iter = apples.begin(); iter != Apples.end(); ++iter)
std::cout << iter->size << ' ';
std::cout << '\n';
}
I am trying to implement a priority queue using using a simple linear approach as explained in Art of Multiprocessor programming. I'm new to c++ and have difficulty troubleshooting.
I've implemented two template classes and am testing them using a simple test method. As I'm not able to pin point the error, I'm pasting all the three classes below for reference.
I know that _M_ construct null not valid comes when trying to construct a string using nullptr, but am not sure where I'm doing that.
The three classes created are given below:
bin.h
#include <mutex>
#include <deque>
#include <memory>
#include <iostream>
using namespace std;
namespace priority
{
template<typename T>
class Bin
{
private:
std::deque<T> v;
std::mutex m;
public:
Bin() {
}
Bin(const Bin &o) {
}
const Bin &operator=(const Bin &other) {
return *this;
}
void put(T item) {
std::lock_guard<std::mutex> lock(m);
v.push_back(item);
}
T *get() {
std::lock_guard<std::mutex> lock(m);
if (v.size() == 0) {
return nullptr;
}
else {
T val = v.front();
T *ptr_val = &(val);
v.pop_front();
return ptr_val;
}
}
bool isEmpty() {
std::lock_guard<std::mutex> lock(m);
return v.size() == 0;
}
};
}
SimpleLinear.h
#include <mutex>
#include <vector>
#include <memory>
#include "Bin.h"
namespace priority
{
template<typename T>
class SimpleLinear
{
private:
int range;
std::vector<Bin<T>> pqueue;
public:
SimpleLinear(int range){
this->range = range;
for (int i = 0; i < range; i++)
{
pqueue.push_back(Bin<T>());
}
}
void add(T item, int key) {
pqueue[key].put(item);
}
T removeMin() {
for (int i = 0; i < range; i++)
{
T *item = pqueue[i].get();
if (item != nullptr) {
return *item;
}
}
return nullptr;
}
};
}
test.cpp
#include <iostream>
#include <vector>
#include <thread>
#include <algorithm>
#include "SimpleLinear.h"
using namespace std;
using namespace priority;
void te(SimpleLinear<string> s, int thread_id) {
s.add("sundar"+to_string(thread_id), thread_id);
s.add("akshaya"+to_string(thread_id), 3);
s.add("anirudh"+to_string(thread_id), 1);
s.add("aaditya"+to_string(thread_id), 5);
cout << s.removeMin() << endl;
cout << s.removeMin() << endl;
cout << s.removeMin() << endl;
}
int main(int argc, char const *argv[])
{
SimpleLinear<string> s(100);
std::vector<std::thread> v;
for (int i = 0; i < 100; i++)
{
// if (i % 2 == 0)
v.push_back(thread(te, std::ref(s), i));
// else
// v.push_back(thread(t, std::ref(s), i));
}
for_each(v.begin(), v.end(), std::mem_fn(&std::thread::join));
return 0;
}
I'm getting the error:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
terminate called recursively
terminate called recursively
terminate called recursively
Aborted (core dumped)
One reason it crashes is that in SimpleLinear<T>::removeMin when T is std::string, return nullptr constructs a string from nullptr. basic_string::_M_construct null not valid basically says
that std::string(nullptr) was invoked.
Another reason it may crash is that get function returns a pointer to a local variable. Local variables get destroyed when the function returns. This leads to undefined behavior.
A fix:
bool get(T& result) {
std::lock_guard<std::mutex> lock(m);
if (v.empty())
return false;
result = v.front();
v.pop_front();
return true;
}
And invoke it like:
T removeMin() {
T result;
for(int i = 0; i < range; i++)
if(pqueue[i].get(result))
break;
return result;
}
Hi guys I did not know how to title this properly. The query I have is with the implementation of a stack I made. In the code I would assume we could use this->push() or this->pop() but the scope operator is needed(stack::push).. I do not understand Why?
#include <iostream>
#include <stack>
template <class T >
class SpecialStack : std::stack<T>
{
public:
SpecialStack() : isEmpty(true) {};
void push(T element)
{
if (!isEmpty)
{
T LastMin = min_stack.top();
if (element < LastMin)
{
min_stack.push(element);
}
else
{
min_stack.push(LastMin);
}
}else
{
min_stack.push(element);
}
stack::push(element); // works
//this->push(element); // Unhandled Exception
}
T pop()
{
min_stack.pop();
T out = stack::top();
stack::pop();
return out;
}
T getMin()
{
return min_stack.top();
}
private:
std::stack<T> min_stack;
bool isEmpty;
};
int main()
{
SpecialStack<int> s;
s.push(3);
s.push(2);
s.push(1);
s.push(5);
s.push(6);
//cout << s.getMin() << endl;
s.pop();
s.pop();
s.pop();
std::cout << s.getMin() << std::endl;
system("pause");
}
void push(T element) {
...
this->push(element);
}
The last line calls your push function recursively. Since the process never terminates, you are getting your stack overflow exception.
stack::push is the correct way to tell the compiler you want to call an implementation from the parent class.
I am having trouble with stacking values for a deque object defined in a template class stack. When initializing a class stack object and use the push_back() member function of the STL deque class on the initialized object and read the number of elements inside the stack I get zero, yet the terminal told me it pushed values into it. It looks as follows:
Stack header file
#ifndef STACK_HH
#define STACK_HH
#include <iostream>
#include <deque>
template<class T>
class Stack {
public:
Stack(): s() { // <-- creating an empty deque s
s.size() ;
nitems() ;
empty() ;
}
~Stack() {
nitems() ;
empty() ;
}
//Member functions
int nitems() { return s.size() ; }
bool empty() { return (s.size()==0) ; }
void push_back(T c) {
s[s.size()] = c ;
}
T back() {
return s[s.size()] ;
}
void pop_back() {
if (empty()) {
std::cout << "Stack::pop() Error: stack is empty" << std::endl ;
}
}
private:
std::deque<T> s ;
};
#endif
Main script
#include <iostream>
#include <deque>
#include "Stack.h"
using namespace std ;
// Main
int main() {
int LEN = 10;
Stack<double> s ;
// Write doubles into Stack
for (int i=0 ; i<LEN ; i++) {
cout << "pushing value " << i*i << " in stack s" << endl ;
s.push_back(i*i) ;
}
// Count doubles in fifo
cout << s.nitems() << " value(s) in stack" << endl ;
return 0 ;
}
I was wondering if I should define the deque push_back(), back() and pop_back() functions differently in my Stack header file. Something like void deque < T > ::push_back() and similar for the other ones. But this did not solve it as I already was expecting yet using s.pushback() did not work either.
Any help in solving this problem is kindly appreciated.
EDIT:
Thank you all for the help.
You can indeed use directly the deque methods like that:
template<class T>
class Stack {
public:
Stack(): s() { // <-- creating an empty deque s
}
~Stack() {
}
//Member functions
int nitems() const { return s.size() ; }
bool empty() const { return s.empty() ; }
void push_back(const T& c) {
s.push_back(c) ;
}
const T& back() {
return s.back();
}
void pop_back() {
if (empty()) {
std::cout << "Stack::pop() Error: stack is empty" << std::endl ;
}
s.pop_back();
}
private:
std::deque<T> s ;
};
Why not std::stack?
Assigning to s[s.size()] doesn't add new elements:
Notes
Unlike std::map::operator[], this operator never inserts a new element into the container.
From http://en.cppreference.com/w/cpp/container/deque/operator_at.
Use s.push_back(new_element) to add new element.
Last element is s[s.size() - 1] or, better, s.back().
s.size(), s.size() and empty() in constructor and destructor do nothing.
From what I've understood correctly:
scoped_ptr: no overhead, cannot be copied or moved.
unique_ptr: no overhead, cannot be copied, can be moved.
shared_ptr: some overhead (reference counting), can be copied.
Having said that, if there is a need for several owners, then shared_ptr should be used.
Now, in this program below which is a simple implementation of stack in C++. I don't understand which type of smart pointer should be used.
The reason I'm asking this question because both unique_ptr as well as shared_ptr cannot be copied and that is exactly what I'm doing in this implementation of simple stack. I've commented out //HERE in the program where I'm using C++ pointers and if you read the program properly you'll see how the data is getting copied in pretty much all the functions.
GameStateStack.h
#ifndef _H_GAMESTATE_
#define _H_GAMESTATE_
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <memory>
class node
{
public:
std::string gameState;
node * nextGameState; // HERE
};
class GameStateStack
{
private:
node * _topState; // HERE
void Destory();
public:
int gameStatesCount;
void PushGameState(std::string element);
void PopGameState();
std::string CurrentGameState();
GameStateStack();
~GameStateStack();
};
extern GameStateStack state;
#endif
GameStateStack.cpp
#include <iostream>
#include <stdlib.h>
#include <string>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <memory>
#include "GameStateStack.h"
#include "template.h"
GameStateStack state;
GameStateStack::GameStateStack()
{
_topState = NULL;
gameStatesCount = 0;
}
GameStateStack::~GameStateStack()
{
}
void GameStateStack::PushGameState(std::string gameStateName)
{
node *newTopState = new node; // HERE
if (_topState == NULL)
{
newTopState->gameState = gameStateName;
newTopState->nextGameState = NULL;
_topState = newTopState;
gameStatesCount++;
}
else
{
newTopState->gameState = gameStateName;
newTopState->nextGameState = _topState;
_topState = newTopState;
gameStatesCount++;
}
}
void GameStateStack::PopGameState()
{
if (_topState == NULL)
std::cout << "Error: no gamestates available to pop";
else
{
node * old = _topState; // HERE
_topState = _topState->nextGameState;
delete(old);
gameStatesCount--;
}
}
std::string GameStateStack::CurrentGameState()
{
node *temp; // HERE
temp = _topState;
return temp->gameState;
}
void GameStateStack::Destory()
{
node *abc; // HERE
delete _topState;
delete abc->nextGameState;
}
Here is how your stack could be implemented using a std::unique_ptr. Note the use of std::move() to re-assign the std::unique_ptr leaving the original pointing at nothing.
Also, instead of if(topState == NULL) I have used the more idiomatic if(topState). A std::unique_ptr returns true if it points somewhere or false if it does not.
Also standard C++ dictates that we should not begin variable names with a leading _.
#include <string>
#include <memory>
#include <iostream>
struct node
{
std::string gameState;
std::unique_ptr<node> nextGameState;
~node()
{
std::cout << "deleting: " << gameState << '\n';
}
};
class GameStateStack
{
// should not use _ to begin variable names in std C++
std::unique_ptr<node> topState;
int gameStatesCount;
public:
GameStateStack();
void PushGameState(std::string gameStateName);
void PopGameState();
std::string CurrentGameState();
void Destory();
};
GameStateStack::GameStateStack()
: gameStatesCount(0) // initialize here
{
//topState = NULL; // no need to initialize unique_ptr
//gameStatesCount = 0; // not here
}
void GameStateStack::PushGameState(std::string gameStateName)
{
std::unique_ptr<node> newTopState(new node);
newTopState->gameState = gameStateName;
newTopState->nextGameState = std::move(topState);
topState = std::move(newTopState);
gameStatesCount++;
}
void GameStateStack::PopGameState()
{
if(!topState)
std::cout << "Error: no gamestates available to pop";
else
{
topState = std::move(topState->nextGameState);
gameStatesCount--;
}
}
std::string GameStateStack::CurrentGameState()
{
if(topState)
return topState->gameState;
return "error: nothing on stack"; // error
}
void GameStateStack::Destory()
{
// deleting topState will first destroy the pointed to
// node's own unique_ptr<node> nextGameState
// which in turn will first delete its own nextGameState etc...
topState.reset();
}
int main()
{
GameStateStack stack;
std::cout << "\ndestroy test" << '\n';
stack.PushGameState("a");
stack.PushGameState("b");
stack.PushGameState("c");
stack.PushGameState("d");
stack.PushGameState("e");
stack.PushGameState("f");
stack.Destory();
std::cout << "\npush-pop test" << '\n';
stack.PushGameState("a");
stack.PushGameState("b");
stack.PushGameState("c");
std::cout << stack.CurrentGameState() << '\n';
stack.PopGameState();
stack.PushGameState("d");
stack.PushGameState("e");
std::cout << stack.CurrentGameState() << '\n';
stack.PopGameState();
std::cout << stack.CurrentGameState() << '\n';
stack.PopGameState();
std::cout << stack.CurrentGameState() << '\n';
stack.PopGameState();
std::cout << stack.CurrentGameState() << '\n';
stack.PopGameState();
std::cout << stack.CurrentGameState() << '\n';
stack.PopGameState();
}
Here an unique_ptr is perfectly fine, especially if you return the CurrentGameState by value as you are doing.
Your top should be a unique_ptr<node>& but since there will be no state at the beginning you could use a std::reference_wrapper to wrap it.
Of course if you plan to return a game state by reference or pointer things will change, because popping a state would invalidate the contained state (unless it's dynamically allocated and then set).