2011-05-11 69 views
0

請參閱下面的重要編輯!C++ OIS Segfault幾乎完全相同的功能工作

大家好,我很難找出爲什麼這段錯誤正在發生。我正在使用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編寫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內(它僅僅是一個包含內存分配和啓動()和shutdown()調用的std :: stack的包裝)

對不起,命名約定的差異導致了任何混淆出於某種原因,我決定使用_underscores_for_some_reason,但我還沒有完全改變它。在此先感謝,埃爾。希望你能解決我的問題,如果我沒有提供足夠的細節,請告訴我。


編輯: 最近升級到Ubuntu納蒂獨角鯨我不能讓調試器正常工作後,它只是崩潰的電腦。我使用Code :: Blocks,並且我不知道如何在IDE之外使用調試器或編譯器(可惜我知道,但是我會在某天學習)。很抱歉,我無法使用調試器。


編輯: 針對GMAN的評論,即使我檢查空,我仍然得到段錯誤

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()的其他方法也能正常工作。再次感謝! :)


重要編輯: 看來,這其實是造成麻煩的防窺視功能,但只能從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時才返回一個不同的地址?有人請幫助我!

+3

has'mStateManager-> peek()'返回null嗎? – GManNickG 2011-05-11 19:47:23

+0

我也懷疑GMan。 – 2011-05-11 19:48:17

回答

1

當您檢查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; 
}; 

編輯:我編輯的代碼來打印每一個分支,它是如何通過跟蹤。

+0

非常不幸,對我來說,當我得到一個段錯誤時,調試器似乎崩潰在code :: blocks(沒有嘗試過任何其他方式)。這從來沒有發生過任何其他項目,但我在3天前剛剛升級到Natty Narwhal。有什麼方法可以測試它沒有斷點,也許一些忙碌的std :: cout語句?編輯:道歉,我現在收到一些消息,我編輯我的帖子。 – Ell 2011-05-11 20:02:07

+0

再次非常抱歉這些編輯,但我無法讓調試器正常工作。用std :: cout替代它們的斷點是我所能做的,而且我仍然得到一個沒有消息的段錯誤。抱歉! – Ell 2011-05-11 20:24:17

+0

@Ell,我編輯了代碼來使用COUT跟蹤,因爲調試器在你的機器上壞了。 – 2011-05-11 20:39:13

相關問題