2011-05-11 5 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; 
}; 

는 segfault가 KEY_PRESSED의 첫 번째 줄이 실행되지 않는 KEY_PRESSED 만에 무슨 일이 일어나고 있기 때문에, 난 단지 추측 할 수 그것을 일으키는 것은 const OIS::KeyEvent&입니다.

그리고 이상한 점은 완벽하게 작동하는 거의 동일한 3 가지 다른 기능이 있다는 것입니다.

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 안에있는 상태 스택 (메모리 할당과 시작() 호출과 shutdown() 호출을 가진 std :: stack의 래퍼 일뿐입니다)

명명 규칙의 차이로 인해 불편을 끼쳐 드려 죄송합니다. 웬일인지 use_underscores_for_some_reason으로 결정했기 때문에 그것을 바꾸는 데 어려움이 없었습니다. 미리 감사드립니다. 당신이 내 문제를 해결할 수 있기를 바라며, 충분한 세부 사항을주지 않았다면 알려주십시오.


편집 : 최근에 나는 디버거가 제대로 동작하지 않습니다 우분투 단정 한 일각 고래로 업그레이드 한 후 , 그냥 컴퓨터를 충돌합니다. Code :: Blocks를 사용하고 IDE 외부에서 디버거 나 컴파일러를 사용하는 방법을 알지 못합니다. (슬픈 아시 겠지만, 언젠가는 배워야 할 것입니다.) 죄송합니다. 디버거를 사용할 수 없습니다.


편집 : G 맨의 의견에 대응하여, 내가 널 확인하더라도 내가 널 (null)을 확인하는 올바른 방법 먹으 렴 확실하지 않습니다 만, 난 아직도 세그먼테이션 폴트 (segfault)

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() 함수가 호출 된 함수에서 message 매개 변수를 설정하면 이러한 결과를 얻게됩니다.

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

'mStateManager-> peek()'이 null을 반환 했습니까? – GManNickG

+0

내 의심도, GMan. –

답변

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

불행히도 나를 위해, 디버거는 코드 :: 블록 (다른 방법으로 시도하지 않은) 내에서 segfault를 얻을 때 충돌하는 것 같습니다. 이것은 다른 어떤 프로젝트에서도 발생하지 않았지만 약 3 일 전에 Natty Narwhal로 업그레이드했습니다. 중단 점없이 테스트 할 수있는 방법이 있을까요? 아마도 대단한 std :: cout 문이 있을까요? 편집 : 죄송합니다, 지금은 몇 가지 메시지를 얻을, 난 내 게시물을 편집합니다. – Ell

+0

다시 한 번 말씀 드리지만이 디버깅을 제대로 처리 할 수는 없습니다. breakpoints를 std :: cout으로 대체하는 것은 내가 할 수있는 것이고 여전히 메시지가없는 segfault를 얻는다. 죄송합니다! – Ell

+0

@Ell, 컴퓨터에서 디버거가 손상 되었기 때문에 COUT 추적을 사용하도록 코드를 편집했습니다. –

관련 문제