2011-09-10 2 views
2

시작 위치를 모르겠습니다 ... 프로그램을 닫을 때 Visual Studio에서 계속 힙 손상 오류가 발생합니다. 그것이 부서지는 위치는 다양합니다. 40 시간 이상 동안 나는 (스마트 포인터 제거, 구현 숨기기 제거, 스마트 포인터 재 추가, 모든 클래스를 복사 불가능하게 만들기, 소멸자를 비공개로 만드는 등) 코드를 변경하는 데 소비했다. stack : boost :: shared_ptr 및 std :: shared_ptr과 관련이있다. (도움이 될지 알아보기 위해 이들 사이를 전환했다.) CLevel 클래스와 관련된 시간의 75 %가 shared_ptr에 의해 삭제되었다.힙 손상

소멸자를 비공개로 만들고 삭제할 함수를 만든 후에 CLevel에 대한 포인터에서 delete를 호출하는 것을 제한했다고 생각했습니다. 그것이 바로 나에게 오류를 줬던 직후의 시간의 50 %와 같다. 나는 CLevel에 들어가서 각 변수가 잘 삭제되었는지 확인하기 위해 봤고, 코드는 기본 클래스로 내려 가서 종료했다. 힙 오류가 발생한 exit에 있었다. 그러나 나는 무엇이 잘못되었는지를 알 수 없었고, 항상 거기에 오류를주지는 않았다. 때로는 실수를 저질렀고 전에도 믿는다. 어떤 문제가 다른 클래스에서 발생했기 때문에이 문제를 찾기가 어렵습니다. (난 그냥 CEntity 또는 CEntityManager라고 생각합니다.)

클래스 구현의 스마트 포인터를 제거한 후 클래스의 새 인스턴스 (CLevel 및 CEntity를 구체적으로 지정)를 요청했을 때 이상한 일을하는 것이 부스트라고 생각했습니다. Application.run()이 종료 된 후 오류가 발생했습니다 (스마트 포인터가 내부에서 실행 됨). 호출 스택은 "스칼라 삭제 소멸자"직후 또는 약간 후에 오류가 발생했음을 보여주었습니다.

많은 경우 휴식 시간은 무료였습니다. 이 시점에서 realloc.c에 있습니다. 이 오류는 한 달만이 다. 프로그램 종료시 어떤 수업도 삭제하지 않으려 고 결심했다. 그러나 나는 그런 식으로 가고 싶지 않다. 만약 내가 원한다면 어떻게 될까? 출구에서 일어나는 일은 나중에 끝나나요? 몇 분 전에 출구에서 오류가 두 번 발생했습니다. 그 중 하나는 ALLEGRO_EVENT_QUEUE 및 ALLEGRO_TIMER에 대한 스마트 포인터와 관련이있는 것으로 보였습니다. 일반 포인터로 만들고 수동으로 삭제했으며 두 번째 포인터는 사라졌습니다.

는 지금,이 호출 스택입니다!

NTDLL.DLL 771b0474() 프레임 아래에 잘못된 및/또는 가 누락 될 수있다, NTDLL.DLL로드없는 문자] NTDLL.DLL! 7716afc3()
NTDLL.DLL! 7716b0ad() NTDLL.DLL! 77,195,665()
NTDLL.DLL! 77,172,990() NTDLL.DLL! 77,195,665()
NTDLL.DLL! 77,172,990() NTDLL.DLL! 77121fec ()

msvcr100d.dl l! _realloc_base (void * pBlock, unsigned int newsize) 줄 85 + 0x17 바이트 msvcr100d.dll! realloc_help (void * pUserData, unsigned int * pnNewSize, int nBlockUse, const char * szFileName, int nLine, int fRealloc) 줄 832 + 0x10 바이트 Cmsvcr100d.dll (void * pUserData, 부호없는 int nNewSize, int nBlockUse, const char * szFileName, int nLine) 줄 1040 + 0x1b 바이트 C++ msvcr100d.dll! realloc (void * pUserData, 부호 INT nNewSize) 라인 (60) + 0x13의 바이트 C++ 알레그로-5.0.4-모노리스-MD-debug.dll! 636d78c0()
알레그로-5.0.4-모노리스-MD-debug.dll! 636e0474()
allegro-5.0.4-monolith-md-debug.dll! 636d11fe ()
allegro-5.0.4-monolith-md-debug.dll! 636d0905()
알레그로 5.0.4-monolith-md-debug.dll! 636d0703() Project Nairim.exe! Application :: ~ Application() 104 + 0xf bytes C++ 프로젝트 Nairim.exe! 응용 프로그램 :: 스칼라 삭제 소멸자 (+) 0x2b 바이트 C++ 프로젝트 Nairim.exe! main() 줄 8 + 0x2b 바이트 C++ 프로젝트 Nairim.exe! __ tmainCRTStartup() 라인 (555)의 0x19 바이트 + C 프로젝트 Nairim.exe! mainCRTStartup() 선 371 C KERNEL32.DLL! 750f339a() NTDLL.DLL! 77119ed2()
NTDLL.DLL! 77119ea5 ()

이 그것이 Deleter가 기능 (에 왔을 때이 문제라고 생각 코드는 참고 :.이 처음 한 달 전에 나타나기 시작하면이 기능은 존재하지 않음)

void PN::CLevelManager::destroyLevel(const pLevel _ptr) 
{ 
    assert(LevelMgr.get() != NULL); 
    std::cout << std::endl << LevelMgr.get(); 
    auto iter = std::find(LevelMgr->m_levelList.begin(), LevelMgr->m_levelList.end(), _ptr); 
    if (iter != LevelMgr->m_levelList.end()) 
     LevelMgr->m_levelList.erase(iter); 
    delete _ptr; 
} 

다른 것들이 있습니다.

이 내 전체 코드입니다 (이것은 많은입니다) : https://github.com/NaturalDre/Nairim

코드가 끔찍 보이거나 심하게 나는 사과 구조화 그래서 만약 내가 독학 프로그래머입니다.

누군가가 나를 향해이 문제를 지적하면 좋을 것입니다. 이런 종류의 물건은 나를 실망시킵니다. 나는 컴퓨터가 모든 것이 고정되어 있고 가변적이지 않기를 좋아한다. (만일 당신이 이것을한다면, 그것이 당신이 기대하는 바가 아니더라도 일어날 것이다.) 이 버그는 주위를 뛰어 다니고 저 같은 것들이 나를 미치게 만듭니다. 프로그램의 관련 데이터가 수정되지 않습니다. CLevel은 파일을 읽고, 맵을 만든 다음, 필요할 때 그 파일을 그립니다.

또한 많은 것들이 급속하게 변경되어 일부 항목이 이상하게 보일 수도 있고 완전히 구현되지 않았을 수도 있습니다.

+2

와우, 정말 오랜 질문입니다. –

+0

힙을 손상 시키면 임의의 위치에서 문제를 잡는 것이 당연합니다. 당신은 비슷한 질문에 대한 내 대답을 읽을 수 있습니다 : http://stackoverflow.com/questions/6557779/memory-allocation-heap-corruption-in-stdstring-constructor/6557811#6557811 –

+4

당신은 잘못된 장소를 찾고 있습니다. 그 카나리아가 죽은 이유. 광산의 다른 구석에서 메탄 누출이 훨씬 일찍 발생했습니다. ''헤더를 사용하십시오. http://msdn.microsoft.com/en-us/library/974tc9t1.aspx –

답변

2

바쁜 시간은 WinDbg, GFlags, and AppVerifier입니다. 이들은 이전에 프로그램을 추락시킬 수있는 도구로, 메모리 손상이 발생한 곳을 디버거로 깰 수 있습니다.

0

나는 AppVerifier가 좋은 방법이라는 것을 확인할 수 있습니다. 나 자신을 사용하여 일부 불쾌한 버그에 대한 그것은 잘 작동합니다. WinDbg 및 GFlags를 사용해 보지 않았지만 App Verifier 및 Visual Studio는 문제가 발생한 위치를 명확하게 보여주었습니다.

0

AppVerifier는 VS 2008 이후에 지원되지 않습니다. C++ Memory Validator와 같은 몇 가지 대안을 사용할 수 있습니다. 매우 유용하고 강력한 도구입니다.