문제

나는 게임을하고 있고 현재 입력을 처리하는 부분을 연구하고 있습니다. 여기에는 세 가지 수업이 참여하고 있습니다 ProjectInstance 레벨과 물건을 시작하는 수업에는 GameController 입력을 처리하고 a PlayerEntity 이것은 GameController. 수준을 시작하면 ProjectInstance가 GameController, 그리고 그것은 그것을 부를 것입니다 EvaluateControls 게임 루프 내부에서 호출되는 단계 메소드의 메소드. 그만큼 EvaluateControls 메소드는 다음과 같습니다.

void CGameController::EvaluateControls(CInputBindings *pib) {
    // if no player yet
    if (gc_ppePlayer == NULL) {
        // create it
        Handle<CPlayerEntityProperties> hep = memNew(CPlayerEntityProperties);
        gc_ppePlayer = (CPlayerEntity *)hep->SpawnEntity();
        memDelete((CPlayerEntityProperties *)hep);
        ASSERT(gc_ppePlayer != NULL);
        return;
    }

    // handles controls here
}

이 기능은 올바르게 호출되며 어설 싱은 결코 트리거되지 않습니다. 그러나이 기능이 호출 될 때마다 gc_ppePlayer NULL로 설정됩니다. 보시다시피 범위를 벗어나는 로컬 변수가 아닙니다. 유일한 곳 gc_ppePlayer NULL으로 설정할 수 있습니다. 생성자 또는 파괴자에있을 수 있으며, 그 중 어느 것도 호출 사이에 호출되지 않습니다. EvaluateControls. 디버깅 할 때 gc_ppePlayer 수익 전에 정확하고 예상 값을받습니다. F10을 한 번 더 누르면 커서가 닫는 브레이스에 있으면 값이 0xffffffff로 변경됩니다. 나는 여기서 상실하고있다. 어떻게 이런 일이 일어날 수 있습니까? 누구나?

도움이 되었습니까?

해결책

릴리스 또는 디버그 구성을 디버깅하고 있습니까? 릴리스 빌드 구성에서 디버거에서 볼 수있는 내용이 항상 사실은 아닙니다. 최적화가 이루어지면 시계 창이보고있는 것처럼 기발한 값을 보여줄 수 있습니다.

실제로 어서 트리거링을보고 있습니까? Asserts는 일반적으로 릴리스 빌드에서 컴파일되어 있으므로 릴리스 빌드를 디버깅하고 있다고 생각합니다.

디버그 버전의 소프트웨어를 작성 한 다음 GC_PPEPLAYER가 실제로 무효인지 확인하는 것이 좋습니다. 그것이 실제로 그렇다면, 아마도 당신은이 포인터가 무시되는 어떤 종류의 메모리 힙 손상을보고있을 것입니다. 그러나 그것이 기억 부패라면, 그것은 일반적으로 당신이 묘사하는 것보다 훨씬 덜 결정적 일 것입니다.

제쳐두고, 이와 같은 글로벌 포인터 값을 사용하는 것은 일반적으로 나쁜 관행으로 간주됩니다. 진정으로 단일 객체이고 전 세계적으로 액세스 할 수 있어야하는 경우 싱글 톤 클래스로 교체 할 수 있는지 확인하십시오.

다른 팁

시계점을 설정하십시오 gc_ppePlayer == NULL 그 표현식의 값이 (널 또는 널에서) 변하면 디버거는 정확히 어디에서 일어난 일을 지적합니다.

그것을 시도하고 무슨 일이 일어나는지 확인하십시오. 너무 작은 메모리에 대한 문명이없는 문자열 또는 mempcy 복사를 찾으십시오. 일반적으로 글로벌/스택 변수가 무작위로 쓰여지는 문제의 원인입니다.

VS2005에서 Watchpoint를 추가하려면 (Brone의 지침)

  1. 브레이크 포인트 창으로 이동하십시오
  2. 새로운 클릭,
  3. 데이터 중단 점을 클릭하십시오. 입력하다
  4. &gc_ppePlayer 주소 상자에 다른 값을 내버려 두십시오.
  5. 그런 다음 실행하십시오.

언제 gc_ppePlayer 변경, 중단 점이 적용됩니다. - 화장실

나의 첫 번째 생각은 spawnentity ()가 memdelete ()가 호출 될 때 "지워진"내부 멤버에게 포인터를 반환하고 있다고 말하는 것입니다. 포인터가 0xffffffff로 설정 될 때 나에게 명확하지 않지만, Memdelete ()로 호출하는 동안 발생하면 ASSERT가 발사되지 않는 이유를 설명합니다. 0xffffffff는 NULL과 동일하지 않습니다.

전체 코드 기반을 재건 한 지 얼마나 되었습니까? 나는 단순히 전체 솔루션을 재건함으로써 이와 같은 기억 문제를 보았습니다.

함수의 끝에서 스텝 오버 (F10) 대신 (F11)로 단계를 시도해 보셨습니까? 예제에는 로컬 변수가 표시되지 않지만 단순성을 위해 일부를 남겨 두었을 것입니다. 그렇다면 F11은 해당 변수 중 하나에 대한 파괴자로 (희망적으로) 단계적으로 들어가서 그 중 하나가 문제를 일으키는 지 확인할 수 있습니다.

당신은 "핵심에 팬들고"가 있습니다.

동적 초기화는 메모리의 다양한 비트 (SIC)를 덮어 쓰는 것입니다.

직접적으로 또는 간접적으로 글로벌을 덮어 쓰고 있습니다. 힙에 대한 메모리의 글로벌은 어디에 있습니까?

이진은 문제가 사라질 때까지 동적으로 초기화 된 부분을 자릅니다. (한 번에 절반의 의견, 재귀 적으로)

어떤 플랫폼에 있는지에 따라 이러한 종류의 메모리 문제를 신속하게 파악할 수있는 도구 (무료 또는 유료)가 있습니다.

내 머리 꼭대기에서 :

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top