请参阅下面的重要编辑内容!
大家好我无法弄清楚为什么会发生这种段错误。我正在使用Ogre和OIS库。以下是导致它的代码:
bool Troll::Application::keyPressed(const OIS::KeyEvent& event) {
//TODO: Segfault here!
Troll::State* state = mStateManager->peek();
state->key_pressed(event); //This causes the SEGFAULT!!!
return true;
};
key_pressed函数:
void Troll::RootState::key_pressed(const OIS::KeyEvent& event) {
std::cout << "You got here" << std::endl; //this isnt printed!
std::cout << "Key Pressed: " << event.key << std::endl;
};
因为在key_pressed上发生了segfault,但是key_pressed的第一行没有被执行,我只能猜测它正在传递导致它的const OIS::KeyEvent&
。
关于这一点的奇怪之处在于我还有其他三个几乎完全相同的功能(但对鼠标而言)可以完美运行。
bool Troll::Application::mouseMoved(const OIS::MouseEvent& event) {
mStateManager->peek()->mouse_moved(event);
return true;
};
void Troll::RootState::mouse_moved(const OIS::MouseEvent& event) {
std::cout << "Mouse Moved: rel x = " << event.state.X.rel << std::endl;
std::cout << " rel y = " << event.state.Y.rel << std::endl;
std::cout << " abs x = " << event.state.X.abs << std::endl;
std::cout << " abs y = " << event.state.Y.abs << std::endl;
};
我正在创建一个基本的状态系统,所以我可以使用OIS库开始为Ogre3D编写应用程序以进行输入。我有一个Application类,它充当鼠标和键盘的输入监听器。以下是它的设置......
void Troll::Application::setup_ois() {
//create a parameter list for holding the window handle data
OIS::ParamList pl;
size_t windowHnd = 0;
//we need the window handle to setup OIS
std::ostringstream windowHndStr;
mWindow->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd;
//add the handle data into the parameter list
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
//create the input system with the parameter list (containing handle data)
mInputManager = OIS::InputManager::createInputSystem(pl);
//true in createInputObject means we want buffered input
mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, true ));
mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, true ));
//set this as an event handler
mKeyboard->setEventCallback(this);
mMouse->setEventCallback(this);
};
应用程序类将鼠标移动,按下按钮和击键中继到状态堆栈顶部的Troll :: State(我正在制作的框架称为Troll),该堆栈位于Troll :: StateManager内部(仅仅是带有内存分配和startup()和shutdown()调用的std :: stack的包装器
很抱歉,由于某种原因,我决定使用use_underscores_for_some_reason而命名约定的差异引起的任何混淆,我还没有改变它。在此先感谢,ell。希望你能解决我的问题,如果我没有提供足够的细节,请通知我。
编辑: 在最近升级到Ubuntu Natty Narwhal后,我无法使调试器正常工作,它只是崩溃了计算机。我使用Code :: Blocks并且我不知道如何在IDE之外使用调试器或编译器(我知道很难过,但有一天我会学习)。很抱歉,我无法使用调试器。
编辑: 回应GMan的评论,即使我检查null,我仍然会得到段错误
bool Troll::Application::keyPressed(const OIS::KeyEvent& event) {
//TODO: Segfault here!
Troll::State* state = mStateManager->peek();
if(state == 0) {
std::cout << "State is null!" << std::endl;
};
state->key_pressed(event);
return true;
};
虽然我不确定这是检查null的正确方法吗?此外,使用peek()的其他方法也能正常工作。再次感谢! :)
重要编辑:
事实上,它实际上是导致故障的peek函数,但只有在从keyPressed
函数调用时才会出现问题。我通过向peek()添加一个参数来发现这一点,以便它将打印它返回的状态对象的地址以及消息。通过将message参数设置为调用peek()函数的函数,我得到了这些结果。
Root state is: 0x8fdd470
Peeking state... 0x8fdd470 from: Application::frameRenderingQueued()
Peeking state... 0x8fdd470 from: Application::mouseMoved
Peeking state... 0x8fdd470 from: Application::frameRenderingQueued()
Peeking state... 0x8fdd470 from: Application::frameRenderingQueued()
Peeking state... 0x8fdd470 from: Application::frameRenderingQueued()
Peeking state... 0x936cf88 from: Application::keyPressed
Segmentation fault
请注意,当keyPressed函数调用peek方法时,会显示不同的地址。我不明白为什么只有当keyPress函数调用peek时才返回不同的地址?有人请帮帮我!
答案 0 :(得分:1)
检查mStateManager是否为NULL,以及从mStateManager-&gt; peek()返回NULL时会发生什么?
bool Troll::Application::keyPressed(const OIS::KeyEvent& event) {
if (mStateManager == NULL) {
//! set breakpoint on next line
std::cout << "mStateManager is NULL, returning false" << std::endl;
return false;
}
std::cout << "about to call peek" << std::endl;
if (Troll::State* state = mStateManager->peek())
{
std::cout << "about to call key_pressed" << std::endl;
state->key_pressed(event); //Does this still cause a SEGFAULT?
std::cout << "back from key_pressed" << std::endl;
return true;
}
std::cout << "mStateManager->peek() returned NULL, returning false" << std::endl;
return false;
};
编辑:我编辑了代码以打印每个分支,以及如何跟踪它。