请参阅下面的重要编辑!
大家好,我无法弄清楚为什么会发生这种段错误。我正在使用 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 但 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::StateManager 内部的状态堆栈顶部的 Troll::State(我正在制作的框架称为 Troll)(这仅仅是一个带有内存分配和 startup() 和 shutdown() 调用的 std::stack 包装器)
抱歉,由于某种原因,命名约定的差异导致了任何混淆,我决定使用_underscores_for_some_reason,但我还没有来得及改变它。提前谢谢,嗯。希望你能解决我的问题,如果我没有提供足够的细节,请告诉我。
编辑:最近升级到 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;
};
虽然我不确定那是检查空值的正确方法吗?此外,使用 peek() 的其他方法也可以正常工作。再次感谢!:)
重要编辑:
似乎实际上是 peek 函数引起了麻烦,但仅在从该keyPressed
函数调用时。我通过向 peek() 添加一个参数来发现这一点,以便它打印返回的状态对象的地址以及消息。通过将消息参数设置为调用 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 时才返回不同的地址?有人请帮我解决这个问题!