I am trying to implement the Pattern State in C++.
I have my client: Player
State as the interface
and the 2 State: In and Out
This is my In.h:
#ifndef ODA_IN_H
#define ODA_IN_H
#include <vector>
#include "Player.h"
#include "Hand.h"
using namespace std;
class In : public State {
public:
In(Player* player);
void doYouChange();
Card throwCard(int i);
void showHand();
void setHand(vector<Card> &other);
private:
Player* player;
Hand hand;
};
#endif
And the In.cpp:
#include <iostream>
#include "In.h"
using namespace std;
In::In(Player* player) {
this->player = player;
cout << player->getName() <<endl;
}
void In::doYouChange() {
string sth;
do {
cout << player->getName() << ", Do you want to leave for this round?(Yes/No)?";
cin >> sth;
} while (sth != "No" && sth != "Yes");
if (sth == "Yes") {
player->setState(player->getOut());
}
}
Card In::throwCard(int i) {
Card c = hand.getCard(i);
return c;
}
void In::showHand() {
hand.showHand();
}
void In::setHand(vector<Card> &other) {
hand.setHand(other);
}
So the constructor can write out the name, while the doYouChange() method no. And later it breaks totally no message just memory junk:/
I call the doYouChange() from an other class like this:
for (int i = 0; i < playersNb; ++i) {
players[i].doYouChange();
}
The first player okay without name, the on the second it breaks.
I have absolutely no idea. I tried to reimplement and everything but nothing helped.
/****************/
UPDATE:
Creating one Player (as a Client of Pattern State in the constructor I initialize also the states):
Player::Player(string n) {
name = n;
out = new Out(this);
in = new In(this);
this -> state = in;
}
And in the same class with the for I add players in the constructor:
players.push_back(Player(name));
This error will very likely occure due to the fact that player becomes invalid (/destroyed).
Consider the following code:
Player* player = new Player();
In inState(player); // will work
inState->doYouChange(); // will work
delete player;
inState->doYouChange(); // wont work
Without more details we cant give you a concrete solution but just general advices:
Make sure that you know who manages your player objects
Check the cases where these objects become destroyed, try to breakpoint them, do your player objects really become destroyed?
Breakpoint the doYouChange() method and check the player object
Consider using smart pointers to overcome an ownership problem: See std::shared_ptr (there are also many other libraries out there which might provide smart pointers better suiting your needs, e.g Poco or Boost)
Related
I'm working on a C++ project in XCode and I'm getting what appears to be some strange behavior (based on how I understand it). Here's my code:
#include <iostream>
#include <vector>
#include <string>
class beep {
public:
virtual void greet() {
std::cout << "bleep\n";
}
};
class boop : public beep {
public:
void greet() {
std::cout << "bloop\n";
}
};
class beep_master {
public:
std::vector<beep*> beeps;
void beep_everything() {
for (int i = 0; i < beeps.size(); i++) {
beeps[i]->greet();
}
}
};
beep_master factory() {
boop boop1;
boop boop2;
beep_master master;
master.beeps.push_back(&boop1);
master.beeps.push_back(&boop2);
return master;
}
int main(int argc, const char * argv[]) {
beep_master master = factory();
beep_master* ref = &master;
ref->beep_everything();
return 0;
}
I'm running this via XCode, and I'm getting an EXC_BAD_ACCESS in the for-loop in beep_master. Everywhere I've looked on the internet seems to indicate this is due to some memory management issues but I'm not really allocating anything dynamically.
I've noticed that if I move the contents of factory into main that I no longer get the error which leads me to believe it has something to do with boop1 and boop2 going out of scope and making the pointers invalid after the code exits that function.
Noodling on this, I'm beginning to think that this issue is unavoidable without the use of dynamic memory via the new operator and shared_ptr. Is this the right direction, or am I missing something in my setup here?
You are right. The factory function is storing pointers to local variables boop1 and boop2 which go away when the function returns, so you're left with pointers that point to invalid data.
You're pretty much going to have to dynamically allocate your objects to store the pointers in your vector.
I am working on a simple game for which i need to store the game-objects in containers. I want to store them in different std::list (objects that get drawn to the screen every frame, objects that need to be updated every frame, etc) so i can just iterate over all objects of a certain type when i need it. Now some objects have to be in more than one list (some of them get drawn and need to be updated every frame) and sometimes it is necessary to delete one from all lists that contain it. The objects should get deleted when they are removed from all lists. This is a simplified example of what i currently have:
#include <iostream>
#include <memory>
#include <string>
#include <list>
class A
{
public:
A(std::string text)
{
message = text;
}
~A()
{
std::cout << "Deleted: " << message << std::endl;
}
std::string getMessage() { return message; }
private:
std::string message;
};
int main()
{
std::list<std::shared_ptr<A>> list1;
std::list<std::shared_ptr<A>> list2;
if(true) // to create scope
{
std::shared_ptr<A> tmp(new A("Test"));
list1.push_back(std::shared_ptr<A>(tmp));
list2.push_back(std::shared_ptr<A>(tmp));
} // tmp out of scope
// delete the object from both lists:
auto i = std::begin(list1);
while(i != std::end(list1))
{
if(i->get()->getMessage() == "Test");
list1.remove(*i);
list2.remove(*i); // the object gets deleted after this line
}
return 0;
}
It work's but it really seems overly complicated (i'm using C# at work where this task is trivial). I have very little experience with memory management using smart pointers. Am i doing something fundamentally wrong?
I've searched endlessly on SE for a logical explanation for why this is happening. It is probably something very simple that I've overlooked, however I cannot spot it and would really appreciate some assistance with this.
Last week I implemented a class to read the output of a system call from a .ini file and then find and store the required information into custom objects that are then stored in a vector inside a Config class. It is a Singleton config class storing a unique_ptr for each instance of my custom class that is created.
The thing is, when I implemented this last week on my laptop, I had zero issues reading and writing to my member vector and was able to get it working exactly how I needed it. Since pulling to my desktop computer, this vector, and any STL container that I use as a member of my class, throws a segmentation fault when I try to do anything on it, even get it's size.
I've tried to shorten the code below to only include sections that actually use this vector. I have replaced my config with A, and custom class with T, and no matter where I try to use my member container, or any other test STL containers that I add to the class, I get a segfault.
For the record, I am using Qt with C++11.
Update: This example breaks on line 50 of c.cpp when debugging, and anywhere that tries to call the vector.
Debug points to this line in stl_vector.h
// [23.2.4.2] capacity
/** Returns the number of elements in the %vector. */
size_type
size() const _GLIBCXX_NOEXCEPT
/*-> this line */ { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
main.cpp
#include "c.h"
int main(int argc, char *argv[])
{
C *c = C::getInstance();
delete c;
return 0;
}
t.h - Class stores information from file
#include <string>
class T
{
public:
T();
bool Active();
std::string getA();
void setA(std::string);
private:
std::string a;
};
t.cpp
#include "t.h"
T::T()
{
}
bool T::Active()
{
if(a == "")
{
return false;
}
return true;
}
std::string T::getA()
{
return this->a;
}
void T::setA(std::string newa)
{
this->a = newa;
}
c.h - Class stores T objects and parses file for information
#include "t.h"
#include <QDebug>
#include <vector>
#include <algorithm>
#include <iostream>
#include <memory>
#include <sstream>
#include <fstream>
class C
{
public:
static C* getInstance();
private:
C();
static C* instance;
static bool init;
std::vector<std::unique_ptr<T>> t_list;
void readLines(const std::string&);
};
c.cpp
#include "c.h"
bool C::init = false;
C* C::instance = nullptr;
C::C()
{
system("echo this is a test command > a.ini");
instance->readLines("a.ini");
}
C* C::getInstance()
{
if(!init)
{
instance = new C;
init = true;
}
return instance;
}
void C::readLines(const std::string &path)
{
T* new_t;
std::ifstream file(path.c_str());
if(!file.is_open())
{
qDebug() << "Unable to open " << path.c_str();
}
std::ofstream o("test.txt");
std::string line;
while(std::getline(file, line))
{
// Split string before searching
std::stringstream ss(line);
std::string seg;
std::vector<std::string> split;
std::string left, right;
// Search patterns
size_t find_a = line.find("a");
size_t del = line.find(':');
if(find_a != std::string::npos)
{
o << "test_Size: " << t_list.size() << std::endl;
if(new_t->Active())
{
T* temp = new_t;
std::unique_ptr<T> move_t(temp);
t_list.push_back(std::move(move_t));
}
o << "test: " << t_list.size() << std::endl;
std::string n;
// Check if previous ahas any null elements
// Split string to find a
n = line.substr(line.find("a "));
n = n.substr(n.find(" ", +2));
new_t->setA(n);
}
else
{
continue;
}
}
// Add last a
T* t = new_t;
std::unique_ptr<T> move_t(t);
//t_list.push_back(std::move(move_t));
o << "a: " << t_list.back().get()->getA() << std::endl;
o << t_list.size() << std::endl;
o.close();
file.close();
}
UPDATE after code change:
I see two things now: One is that new_t in C::readlines is never initialized, so this could break when new_t->Active() is called a bit later in the function. However, I believe that the main problem you're running into is in C::C(), where it says
instance->readLines("a.ini");
At this point in the execution, C::instance is not yet initialized -- you're only just constructing the object that would later be assigned to it. Because of this, this in the readlines call is invalid, and any attempt to access object members will cause UB. This latter problem can be fixed by just calling
readLines("a.ini");
in which case the currently constructed object (that will later be instance) is used for this. I have no idea what you want to happen for the first, though, so all I can say is: If you want to have a vector<unique_ptr<T>>, you will have to create objects of type T with either new T() or (arguably preferrably) std::make_unique<T>() and put them in there.
I'll also say that this is a rather ugly way to implement a singleton in C++. I mean, singletons are never really pretty, but if you're going to do it in C++, the usual way is something like the accepted answer of C++ Singleton design pattern .
Old answer:
The problem (if it is the only one, which I cannot verify because you didn't provide an MCVE) is in the lines
T move_t = new_T;
std::unique_ptr<Adapter> ptr_t(&move_t); // <-- particularly this one
m_ts.push_back(std::move(ptr_t));
You're passing a pointer to a local object into a std::unique_ptr, but the whole purpose of std::unique_ptr is to handle objects allocated with new to avoid memory leaks. Not only will the pointer you pass into it be invalid once the scope surrounding this declaration is left, even if that weren't the case the unique_ptr would attempt to delete an object that's not on the heap at the end of its lifecycle. Both problems cause undefined behavior.
To me, it looks as though you really want to use a std::vector<T> instead of std::vector<std::unique_ptr<T>>, but that's a design issue you'll have to answer yourself.
Answering my own question here. I am trying to call a member variable from within the constructor of the object that holds it, so the vector I am trying to access is not yet instantiated and doesn't exist in memory. That is what causes the Segmentation fault to occur, I am trying to access memory that is not allocated yet, hence any call acting on any member of my C class was causing this issue.
I fixed this problem by adding a public function to the class that then calls the private readLines() function. I call that public function from the object that will take ownership of it, and since this occurs after it has been instantiated, the memory is accessible and the problem disappears.
I have the classes Team and Player. Every Team member has an object vector playerlist with his players stored in. Every player now has some attributes like ID. Now i want to transfer a Player to a Team . So i created a function for this.
First i want to findout if the Player b maybe is already a member of Team a, in which case a message should be printed out. But i failed in writing a function which does this.
Here is my try(the search starts in the if loop, where i want to find out if Player b is member of Team a)
#include <vector>
#include <string>
#include <iostream>
using namespace std;
class Player
{
public:
private:
};
class Team
{
public:
vector<Player> getplayerlist(){
return playerlist;
}
string getteamname(){
return teamname;
}
void playerbuy(Team a, Player b)
{
vector<Player> playerlist;
playerlist = a.getplayerlist();
if (find(playerlist.begin(), playerlist.end(), 5) != playerlist.end()) {
}
else {
cout << "This player is not member of " << a.getteamname();
}
}
private:
vector<Player> playerlist;
string teamname;
};
int main()
{
return 0;
}
I got the error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Player' (or there is no acceptable conversion). I figured out i comes from the line
if (find(playerlist.begin(), playerlist.end(), 5) != playerlist.end())
The =! playerlist.end() seems to be wrong there. This part of the code is some copy of another code so i don't know what it does. What should i put in there instead ?
And what does the 5 means ?
The error is giving you a good hint: you need to implement an equality operator for class Player. That is what std::find uses to determine if an element has been found.
Alternatively, you can use std::find_if with a custom unary predicate.
I am designing and implementing a class where I have to include two initialization operations using the class's constructors. One is the default initialization (that I think I have done properly) and the other one is the initialization from the user inputs which is supposed to be in the constructor itself(where I still have trouble to write it). I am using separate compilation, so I show the code from the file with the class and the main function from the .cpp file. I am using Dev-C++ and part of the code is below. Thanks for your help.
#include <iostream>
#include <exception>
#include <math.h>
///#include "Exception.h"
#ifndef TRIANGLE_H
#define TRIANGLE_H
using namespace std;
class Triangle
{
private:
double side1;
double side2;
double side3;
double angle_side1_side2;
double angle_side1_side3;
double angle_side2_side3;
public:
//default constructor with default initialization
Triangle::Triangle(): side1(0), side2(0), side3(0), angle_side1_side2(0), angle_side1_side3(0), angle_side2_side3(0)
{
}
//constructor with user inputs, but I know there is something wrong...
Triangle::Triangle(double s1, double s2, double s3)
{
cout<<"enter your own values:"<<endl;
cin>>s1>>s2>>s3;
side1=s1;
side2=s2;
side3=s3;
cout<<"the current lengths of sides of your triangle are: " <<endl;
}
double display_triangle_sides()
{
cout<<side1<<" "<<side2<<" "<<side3<<" ";
}
double display_triangle_Area()
{
double S=(side1+side2+side3)/2; //semiperimeter
double T=sqrt(S*(S-side1)*(S-side2)*(S-side3)); //Heron formula to calculate Area of triangle
return T;
}
};
endif
//*****************************main function below************************
#include <iostream>
#include <exception>
#include "Untitled1.h"
using namespace std;
int main()
{
Triangle tr;
cout<<" length of each side of the current triangle : ";
tr.display_triangle_sides(); //I want to show here the values entered by the users
cout<<endl<<"Here is the Area of the current triangle : " << tr.display_triangle_Area()<<endl;
cout<<"type of triangle:"<<endl;
tr.Type_of_Triangle();
system("Pause");
return 0;
}
A constructor where the user has to enter values manually is appalling design. Are you sure you have been told to do that?
The correct way to do this is something like this
class Triangle
{
Triangle::Triangle(): side1(0), side2(0), side3(0)
{
}
Triangle::Triangle(double s1, double s2, double s3) : side1(s1), side2(s2), side3(s3)
{
}
...
};
int main()
{
double s1, s2, s3;
cin >> s1 >> s2 >> s3;
Triangle t(s1, s2, s3);
...
}
In order words you enter values in the main function, and then you pass the values to the constructor.
The reason that your way of doing things is so bad is that it makes your Triangle constructor only useable in the specific context of the program you are writing now. You should design your classes so that they are reusable in different programs. This is probably a hard thing for you to appreciate now when you're just beginning, since you are focused on just getting one program to work, not thinking about programs you might write in the future.
If you really have been told that you must do this, then you are being taught by an incompetant.
You need to do like this:
int main()
{
cout<<"enter your own values"<<endl;
double s1,s2,s3;
cin>>s1>>s2>>s3;
Triangle tr(s1,s2,s3);
cout<<" length of each side of the current triangle : ";
tr.display_triangle_sides(); //I want to show here the values entered by the users
cout<<endl<<"Here is the Area of the current triangle : " << tr.display_triangle_Area()<<endl;
cout<<"type of triangle:"<<endl;
tr.Type_of_Triangle();
system("Pause");
return 0;
}
Also change consrtructor to
//constructor with user inputs, but I know there is something wrong...
Triangle::Triangle(double s1, double s2, double s3):side1(s1),side2(s2)side3(s3)
{
}
According to your task description you need an opportunity to create different configurations of the object class instances, configurartion of particular instance depends on user input.
So as one of the method to approach your task I advice your to read about programming pattern builder.
Object of class builder is responsible for creation of instances of particular class it offers such advantages as flexiable objects creation and error prevention. I wrote a small example for you:
class Triangle
{
friend class TriangleBuilder;
public:
double display_triangle_sides()
{
cout<<side1;
}
private:
double side1;
Triangle::Triangle(): side1(0){}
Triangle::Triangle(int v): side1(v){}
};
class TriangleBuilder
{
public:
void BuildDefaultTriangle(void)
{
this->m_instance = new Triangle;
}
void BuildCustomTriangle(void)
{
cout << "All right!! Enter side length)\n" << endl;
int tmp;
cin >> tmp;
this->m_instance = new Triangle(tmp);
}
Triangle* getTriangle(void)
{
return this->m_instance;
}
private:
Triangle* m_instance;
};