I'm getting an unhandled exception reading location 0x00000008 (reading NULL value) on the noted line below, relevant methods leading up to the error are included (continued below examples):
Event Methods:
Event::Event(Event::EVENTTYPE type) : eventType(type) { }
KeyEvent Methods:
class KeyboardKeyEvent : public Event {
public:
//...
int GetKey() const;
protected:
//...
};
int KeyboardKeyEvent::GetKey() const {
return this->_scancode; //Errors out here. "this" returns 0x000000
}
KeyboardKeyEvent::KeyboardKeyEvent(int key, Event::EVENTTYPE type) : Event(type), _scancode(key) { }
KeyDownEvent Methods:
KeyboardKeyDownEvent::KeyboardKeyDownEvent(int scancode) : KeyboardKeyEvent(scancode, Event::KEYBOARD_KEYDOWN) { }
Event Handler Methods:
bool EventHandler::EnqueueEvent(Event* event) {
if(event == NULL) return false;
try {
this->_eventQueue.push(event);
} catch (...) {
return false;
}
return true;
}
Event* EventHandler::DequeueEvent() {
if(this->_eventQueue.empty() == false) {
Event* result = new Event(*this->_eventQueue.front());
delete this->_eventQueue.front();
this->_eventQueue.pop();
return result;
}
return NULL;
}
Main Loop Sequence:
if(_eh->HasEvents()) {
Event* nxtEvent = _eh->DequeueEvent();
switch(nxtEvent->GetType()) {
case Event::KEYBOARD_KEYDOWN:
allegro_message("You pressed the %d key!", dynamic_cast<KeyboardKeyDownEvent*>(nxtEvent)->GetKey());
break;
default:
/* DO NOTHING */;
}
delete nxtEvent;
nxtEvent = NULL;
}
I know this is a slicing problem I just don't see why it's happening or how to fix it (Actually, now that I think about it, it's probably a "Can not convert to requested type" error). All throughout when I step through the program _scancode is the appropriate value, but the second the line dynamic_cast<KeyboardKeyDownEvent*>(nxtEvent)->GetKey() runs it throws the error. Double casting as dynamic_cast<KeyboardKeyDownEvent*>(dynamic_cast<KeyboardKeyEvent*>(nxtEvent))->GetKey() fails with the same error as well.
EDIT:
After some tweaking, this variant works perfectly:
if(_eh->HasEvents()) {
switch(_eh->PeekEvent()->GetType()) {
case Event::KEYBOARD_KEYDOWN:
allegro_message("You pressed the %s key!", scancode_to_name(dynamic_cast<KeyboardKeyDownEvent*>(_eh->PeekEvent())->GetKey()));
break;
case Event::MOUSE_BUTTONDOWN:{
Mouse::BUTTONS btn = dynamic_cast<MouseButtonDownEvent*>(_eh->PeekEvent())->GetButton();
if(btn == Mouse::BUTTON2) {
allegro_message("You pressed the %d button!", dynamic_cast<MouseButtonDownEvent*>(_eh->PeekEvent())->GetButton());
}
}
break;
default:
/* DO NOTHING */;
}
}
One solution to avoid slicing is to make the destructor of base class virtual, so in your case you can make ~Event() virtual:
class Event
{
public:
//...
virtual ~Event() {}
};
By the way, I'm wondering why you do the following:
//YOUR CODE : its causing the problem!
Event* EventHandler::DequeueEvent() {
if(this->_eventQueue.empty() == false) {
Event* result = new Event(*this->_eventQueue.front()); // WHY?
delete this->_eventQueue.front(); //WHY?
this->_eventQueue.pop();
return result;
}
return NULL;
}
Why don't you simply do this:
//Use it. Because it should not cause that probem
Event* EventHandler::DequeueEvent() {
if(this->_eventQueue.empty() == false) {
Event* result = this->_eventQueue.front();
this->_eventQueue.pop();
return result;
}
return NULL;
}
In Event* EventHandler::DequeueEvent() you have line
Event* result = new Event(*this->_eventQueue.front()); Here the slicing occurs.
You can do the following:
class Event {
public:
virtual Event* clone() {
// create a new instance and copy all the fields
}
}
Then override clone() in derived classes, e.g.
class KeyboardKeyEvent :public Event {
public:
...
virtual KeyboardKeyEvent* clone(); // note - it returns different type
}
Then change Event* EventHandler::DequeueEvent() :
Event* result = (*this->_eventQueue.front()).clone();
Your DequeueEvent method will always return an Event object, not any of the sub-classes that you are expecting.
Event* result = new Event(*this->_eventQueue.front());
Your Dequeue event should either return the actual reference it is caching, or your base Event class need to provide some sort of virtual copy operation that will provide a real clone.
Why are you copying the Event when you remove it from the queue? That's what is doing the slicing, since you're constructing the base class. Instead, return the pointer that was on the queue to the user.
As noted above, Event should have a virtual ~Event(), so that the recipient of the event can delete it properly. Otherwise, the concrete class destructor will not be properly run.
Event* EventHandler::DequeueEvent() {
if(this->_eventQueue.empty() == false) {
Event* result = this->_eventQueue.front();
this->_eventQueue.pop();
return result;
}
return NULL;
}
Related
I have strange crash on my program. I run the program in a Linux environment.
This is the code:
class classB
{
public:
classB(classA* pi_pCreator)
{
m_pCreator = pi_pCreator;
}
bool DoAction()
{
if(m_pCreator)
{
//do some code
return true;
}
return false;
}
private:
classA* m_pCreator = NULL;
};
void Correlate(classA* pi_pCreator)
{
classB l_oCorrelate(pi_pCreator);
bool res = l_oCorrelate.DoAction();
if (res)
{
return;
}
else
{
pi_pCreator->DoErrorAction();
}
}
I am using crashfind to find the source of the crash and result is referring to this line:
classB l_oCorrelate(pi_pCreator);
Usually the function Correlate is called with a valid pi_pCreator, but also there are some cases with NULL.
Is the constructor of classB is really the problem, or is dereferencing the problem?
For the life of me I cannot understand at all why this program is getting a segmentation error. The issue is that it retrieves an object within the vector container uses a function within the menu class using the get_command() and for some reason after testing the main function line by line this one results in a segmentation fault:
menu->get_command()->execute();
I have tried changing the syntax to create a new command object that stores the returned object from get_command() and changed the index between 0 and -1 and still nothing fixes the error. I have spent at least a couple of hours trying to figure out why but I cannot seem to find a solution.
class Base {
public:
/* Constructors */
Base() { };
/* Pure Virtual Functions */
virtual double evaluate() = 0;
virtual std::string stringify() = 0;
};
class op : public Base
{
public:
op() { };
op(double op1) { operand = op1; }
double evaluate() { return operand; }
string stringify() {
string value = to_string(operand);
return value;
}
private:
double operand;
};
class Command {
protected:
Base* root;
public:
Command() { this->root = nullptr; }
double execute() { return root->evaluate(); }
std::string stringify() { return root->stringify(); }
Base* get_root() { return root; }
};
class Menu {
private:
int history_index; // Indexes which command was last executed, accounting for undo and redo functions
std::vector<Command*> history; // Holds all the commands that have been executed until now
public:
Menu() {
// Constructor which initializes the internal members
history_index = -1;
}
std::string execute() {
// Returns the string converted evaluation of the current command
return to_string(history[history_index - 1]->execute());
}
std::string stringify() {
// Returns the stringified version of the current command
return history[history_index]->stringify();
}
bool initialized() {
// Returns if the history has an InitialCommand, which is necessary to start the calculation
if (history[history_index] != nullptr)
return true;
else
return false;
}
void add_command(Command* cmd) {
// Adds a command to the history (does not execute it), this may require removal of some other commands depending on where history_index is
history.push_back(cmd);
history_index++;
}
Command* get_command() {
// Returns the command that the history_index is currently referring to
return history[history_index];
}
void undo() {
// Move back one command (does not execute it) if there is a command to undo
history_index--;
}
void redo() {
// Moves forward one command (does not execute it) if there is a command to redo
history_index++;
}
};
class InitialCommand : public Command {
protected:
Base* root;
public:
InitialCommand(Base* b) { this->root = b; }
double execute() { return root->evaluate(); }
std::string stringify() { return root->stringify(); }
Base* get_root() { return root; }
};
void main()
{
Menu* menu = new Menu();
InitialCommand* temp = new InitialCommand(new op(7));
menu->add_command(temp);
EXPECT_EQ(menu->get_command()->execute(), 7);
system("PAUSE");
}
You're not doing inheritance right, as you are duplicating fields between Command and InitialCommand that lead to the error.
Both command classes have a Base *root member, and non-virtual execute methods. When you construct a new InitialCommand object, the InitialCommand::root object points at the op that was created for it, while Command::root remains NULL because of the default constructor for Command. Then, when you call menu->get_command(), it will call Command::execute because execute is non-virtual and menu is a Command *. Command::execute will then dereference a NULL root, causing your segmentation error.
Remove the Base *root member from InitialCommand, and pass the parameter to a constructor in Command. You probably want to make some methods like execute virtual.
The problem is that your Command and InitialCommand both have root variable.
InitialCommand* temp = new InitialCommand(new op(7)); will according to your constructor set InitialCommand::root. So Command::root remains uninitialized. Then Menu holds std::vector<Command*>, so InitialCommand* is implicitly converted to Command*.
At alst calling Command::execute will indeed call Command:execute because the method is not virtual. So, the uninitialized Command::root is used -> seg. fault.
Please don't use new. Use smart pointers - std::unique_ptr should be the default way to manage dynamic memory.
That said, your code seems too Java/C# like. This is C++, use value semantics if you can. There's no reason for Menu* menu = new Menu();. Menu menu; is simpler and works the same in your case. Here's a code I would've written
#include <memory>
#include <vector>
#include <string>
using namespace std;//Not a good practice and definitely a big no in header files.
class Base {
public:
/* Constructors */
Base() { };
/* Pure Virtual Functions */
virtual double evaluate() = 0;
virtual std::string stringify() = 0;
};
class op : public Base
{
public:
op() { };
op(double op1) { operand = op1; }
double evaluate() { return operand; }
string stringify() {
string value = to_string(operand);
return value;
}
private:
double operand;
};
class Command {
protected:
std::unique_ptr<Base> root;
public:
Command(std::unique_ptr<Base>&& root):root(std::move(root)) { }
//Be const-correct
double execute() const { return root->evaluate(); }
std::string stringify() const { return root->stringify(); }
Base* get_root() const { return root.get(); }
};
class Menu {
private:
int history_index; // Indexes which command was last executed, accounting for undo and redo functions
std::vector<std::unique_ptr<Command>> history; // Holds all the commands that have been executed until now
public:
Menu() {
// Constructor which initializes the internal members
history_index = -1;
}
std::string execute() const{
// Returns the string converted evaluation of the current command
return to_string(history[history_index - 1]->execute());
}
std::string stringify() const{
// Returns the stringified version of the current command
return history[history_index]->stringify();
}
bool initialized() const{
// Returns if the history has an InitialCommand, which is necessary to start the calculation
if (history[history_index] != nullptr)
return true;
else
return false;
}
void add_command(std::unique_ptr<Command>&& cmd) {
// Adds a command to the history (does not execute it), this may require removal of some other commands depending on where history_index is
history.emplace_back(std::move(cmd));
history_index++;
}
Command* get_command() const {
// Returns the command that the history_index is currently referring to
return history[history_index].get();
}
void undo() {
// Move back one command (does not execute it) if there is a command to undo
history_index--;
}
void redo() {
// Moves forward one command (does not execute it) if there is a command to redo
history_index++;
}
};
class InitialCommand : public Command {
protected:
public:
InitialCommand(std::unique_ptr<Base>&& b): Command(std::move(b)){}
};
// There's no such thing as void main
int main()
{
Menu menu;
auto temp = std::make_unique<InitialCommand>(std::make_unique<op>(7));
menu.add_command(std::move(temp));
//EXPECT_EQ(menu.get_command()->execute(), 7);
system("PAUSE");
}
It uses move semantics which used to not be a beginners concept, but it's such integral part of modern C++ that every C++ programmer must learn it sooner rather than later.
In the code Google Mock test snippet there is an EXPECT_CALL that returns True and an argument reference for 200 times.
How can I let the test only return True every nth time. For example return True each 10th call and otherwise return False.
class MockHandler : public Handler
{
public:
MOCK_METHOD1(RxMsg, bool(Msg &msg));
}
TEST(TestDispatcher, HandlePing)
{
auto mockedHandler = make_unique<MockHandler>();
Msg rxMsg = { REQUEST::REQ_PING, sizeof(DefaultMsg_t), rxMsg.rx,(uint8_t*)"0"};
EXPECT_CALL(*mockedHandler,
RxMsg(_)).Times(checkValue).WillRepeatedly(
DoAll(SetArgReferee<0>(rxMsg), Return(TRUE)));
Dispatcher dispatcher(10, mockedHandler);
for (int i = 0; i < 199; i++)
{
dispatcher.RunToCompletion();
}
}
There are few approaches that might work for you. I like the solution with Invoke as a default action, because it is the most flexible. You didn't provide mcve in your question, so I wrote very simple implementations for the classes you use. Also you made a mistake using unique_ptr for the mock. In 99% of cases is must be shared_ptr, because you are sharing it between testing environment and your System Under Test.
class Msg {};
class Handler {
public:
virtual bool RxMsg(Msg &msg) = 0;
};
class MockHandler: public Handler
{
public:
MOCK_METHOD1(RxMsg, bool(Msg &msg));
};
class Dispatcher {
public:
Dispatcher(std::shared_ptr<Handler> handler): h_(handler) {}
void run() {
Msg m;
std::cout << h_->RxMsg(m) << std::endl;
}
private:
std::shared_ptr<Handler> h_;
};
class MyFixture: public ::testing::Test {
protected:
MyFixture(): mockCallCounter_(0) {
mockHandler_.reset(new MockHandler);
sut_.reset(new Dispatcher(mockHandler_));
}
void configureMock(int period) {
ON_CALL(*mockHandler_, RxMsg(_)).WillByDefault(Invoke(
[this, period](Msg &msg) {
// you can also set the output arg here
// msg = something;
if ((mockCallCounter_++ % period) == 0) {
return true;
}
return false;
}));
}
int mockCallCounter_;
std::shared_ptr<MockHandler> mockHandler_;
std::unique_ptr<Dispatcher> sut_;
};
TEST_F(MyFixture, HandlePing) {
configureMock(10);
for (int i = 0; i < 199; i++) {
sut_->run();
}
}
At the beginning of each test you should call configureMock method that will Invoke ON_CALL macro setting the default action for your mock. Function passed to Invoke can be any function matching the signature of the method you are overwriting. In this case it;s a function that counts how many times mock has already been called and returns appropriate value. You can also assign some particular object to the msg output argument.
I have a class interface function which implements other functions within the class in a specific order:
class Child
{
public:
auto Interface()->bool
{
this->F1(); //I use this just for extra clarity (e.g. not calling global function)
this->F2();
return true;
}
auto F1()->void
{
//Do stuff...
}
auto F2()->void
{
//Do more stuff...
}
};
class Parent
{
public:
Child ChildObj;
auto CallUponChild()->void
{
bool success = ChildObj.Interface();
}
};
I want to wrap the 'Interface()' implementation in a try/catch block:
auto Interface()->bool
{
try{
this->F1();
this->F2();
}catch(...){
//Handle
}
}
However, on the occurance of an error, I wish to attempt the function again, and if that errors, I want to propogate the error back to the Parent class:
auto Interface()->bool
{
int error_count=0;
try{
try{
this->F1();
this->F2();
return true;
}catch(...){
if(error_count<1){this->F1(); this->F2();}
else{throw "Out of tries";}
}
}catch(...){
return false;
}
}
Is using nested try/catch blocks fround upon? Is this the best approach to take?
Something like
auto Interface()->bool
{ int error_count=0;
while (error_count < 1) {
try {
this->F1();
this->F2();
return true;
}
catch(...){
// if (error_count >= 1)
// throw; // to throw original exception
++error_count;
}
};
// throw "Out of tries"; // to throw "Out of tries" exception
return false; // to use the boolean result
}
should be sufficient. If F1() throws an exception in your catch block, your function will return false without incrementing error_count.
It does not seems to be something that the child should handle imho, should that behaviour been handled by the Parent which knows how to deal with their childs? I would go this way:
auto CallUponChild()->void
{
const bool success = ChildObj.Interface();
if (!success) { // maybe if-init if you have a c++17 compiler
// try again
ChildObj.Interface();
}
}
I think the way to handle the child objects should be at Parent level as I said, Child object should do one thing and if it's needed to be done twice(or N) then should'n be their responsibility.
If you want to show how the exception were thrown you can have a look at this:
http://en.cppreference.com/w/cpp/error/throw_with_nested
I am trying to create a state machine. I have created a class called BaseState that all states inherits from. The problem I'm having is that when the sub classes change a BaseState member variable, it does not change the variable for all of the inherited classes. From what I know of programming, this is when I use static. But in my case I get a linker error (LNK2001).
So when I call ChangeState(State::MenuState); inside SplashState, it switches, but switches back since the value in BaseState has not changed.
class StateMachine
{
private:
State _currentState;
std::vector<BaseState*> _baseStates;
void ProcessStateRequest();
public:
StateMachine(InitVar initVar);
~StateMachine();
void Update(float deltaTime);
};
That adds the states like this:
StateMachine::StateMachine(InitVar initVar)
{
_currentState = State::SPLASHSTATE;
for (int i = 0; i < State::EXITSTATE; i++)
{
switch (i)
{
case SPLASHSTATE:
{
_baseStates.push_back(new SplashState(initVar));
break;
}
case MENUSTATE:
{
_baseStates.push_back(new MenuState(initVar));
break;
}
case PLAYSTATE:
{
_baseStates.push_back(new PlayState(initVar));
break;
}
case OPTIONSSTATE:
{
_baseStates.push_back(new OptionsState(initVar));
break;
}
}
}
}
With changing states like this:
void StateMachine::ProcessStateRequest()
{
//if currentState does not match with the new requested state.
if (_currentState != _baseStates[_currentState]->GetNewStateRequest())
{
_baseStates[_currentState]->OnStateExit();
_currentState = _baseStates[_currentState]->GetNewStateRequest();
_baseStates[_currentState]->OnStateEnter();
}
}
Inside basestate.h:
enum State
{
SPLASHSTATE,
MENUSTATE,
PLAYSTATE,
OPTIONSSTATE,
EXITSTATE,
};
class BaseState
{
private:
State _newStateRequest; //Cannot edit this from subclasses. Adding static causes linker error.
protected:
ObjectHandler* _objectHandler;
UIHandler* _uiHandler;
void ChangeState(State newState);
public:
BaseState(InitVar initVar);
~BaseState();
virtual void Update(float deltaTime) = 0;
virtual void OnStateEnter() = 0;
virtual void OnStateExit() = 0;
State GetNewStateRequest()const;
};
The last part of basestate.cpp:
BaseState::BaseState(InitVar initVar)
{
_objectHandler = initVar.objectHandler;
_uiHandler = initVar.uiHandler;
_newStateRequest = SPLASHSTATE;
}
BaseState::~BaseState()
{}
void BaseState::ChangeState(State newState)
{
_newStateRequest = newState;
}
State BaseState::GetNewStateRequest() const
{
return _newStateRequest;
}
MikeCAT in comments gave this answer. Problem solved by doing this;
class BaseState
{
private:
static State BaseState::_newStateRequest;
//State _newStateRequest;
and
#include "BaseState.h"
State BaseState::_newStateRequest;
BaseState::BaseState(InitVar initVar)