C++当几乎相同的功能工作时 OIS 段错误

发布于 2024-11-06 18:44:40 字数 4128 浏览 1 评论 0原文

请参阅下面的重要编辑!

大家好,我无法弄清楚为什么会发生此段错误。我正在使用 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 内部状态堆栈顶部的 Troll::State(我正在制作的框架称为 Troll) :: StateManager (它只是一个 std::stack 的包装器,具有内存分配、startup() 和 shutdown() 调用)

抱歉,由于命名约定的差异导致的任何混淆,由于某种原因,我决定使用_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;
};

尽管我不确定这是检查 null 的正确方法吗?此外,使用 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 时才返回不同的地址?有人请帮我解决这个问题!

See important edit below!

Hi all I'm having trouble figuring out why this segfault is happening. I'm using the Ogre and OIS library. Here is the code that causes it:

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;
};

And the key_pressed function:

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;
};

Because the segfault is happening on key_pressed but the first line of key_pressed isn't being executed, I can only guess that it is passing the const OIS::KeyEvent& that is causing it.

And the weird thing about this is I have three other functions that are almost identical (but for the mouse) which work perfectly.

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;
};

I'm creating a basic state system so I can start writing applications for Ogre3D using the OIS library for input. I have an Application class which acts as an input listener for the mouse and keyboard. Here is how its setup...

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);
};

The application class relays the mouse moves, button pressed and key strokes to the Troll::State (the framework I'm making is called Troll) at the top of the state stack which is inside the Troll:: StateManager (which is merely a wrapper for an std::stack with memory allocation and startup() and shutdown() calls)

Sorry for any confusion the difference of the naming conventions causes for some reason I decided to use_underscores_for_some_reason and I haven't got round to changing it. Thanks in advance, ell. Hope you can solve my problem and please inform me if I haven't given enough detail.


EDIT:
After recently upgrading to Ubuntu Natty Narwhal I cannot get the debugger to work properly, it just crashes the computer. I use Code::Blocks and I don't have a clue how to use a debugger or compiler outside the IDE (sad I know, but I'll get round to learning someday). So sorry, I can't use a debugger.


EDIT:
In response to GMan's comment, even if I check for null, I still get segfaults

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;
};

Although I'm not sure thats the correct way to check for null? Also, other methods using peek() work correctly. Thanks again! :)


Important Edit:
It seems that it is in fact the peek function that is causing trouble, but only when called from the keyPressed function. I discovered this by adding a parameter to peek() so that it would print the address of the state object it return as well as the message. By setting the message parameter to the function from where the peek() function is called, I got these results.

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

Notice that when the keyPressed function calls the peek method, a different address is shown. I cannot see why a different address is being returned only when the keyPress function calls peek? Somebody please help me with this!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜`诱少女 2024-11-13 18:44:40

当您检查 mStateManager 是否为 NULL 以及从 mStateManager->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;
};

编辑:我编辑了代码来打印每个分支,以及它是如何追踪的。

What happens when you check for mStateManager being NULL, and for NULL being returned from mStateManager->peek()?

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;
};

EDIT: I edited the code to print each branch, how it was traced through.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文