2012-09-08 3 views
1

다음 코드는 디버거가 delete[] 연산자에 도달 할 때마다 힙 손상을 일으키는 것으로 보입니다. 헤더 파일에 extern으로 정의 된 다음 전역 .cpp 파일의 전역 범위에서 선언 된 구조체의 전역 배열을 삭제하려고합니다.전역 배열을 삭제할 때 힙 손상

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    switch(msg) 
    { 
    case WM_CREATE: 
     { 
     int main_win_x, main_win_y; 

     tiles_horiz = 10; //temp code 
     tiles_vert = 10; //temp code 
     num_mines = 5; //temp code 

     main_win_x = (tiles_horiz * 22) + 20; 
     main_win_y = (tiles_vert * 22) + 20; 

     MoveWindow(hwnd, 100, 100, main_win_x, main_win_y, TRUE); 

     tiles_total = (tiles_horiz * tiles_vert); 
     tile_array = new tile[tiles_total]; 

     SetupPlayField(); 
     DrawInitTiles(hwnd); 
     } 
     break; 
    case WM_SIZE: 
     { 

     } 
     break; 
    case WM_CLOSE: 
     delete[] tile_array; 
     DestroyWindow(hwnd); 
     break; 
    case WM_DESTROY: 
     PostQuitMessage(0); 
     break; 
    default: 
     return DefWindowProc(hwnd, msg, wParam, lParam); 
    } 
    return 0; 
} 

지난 며칠 동안 포럼에서 다양한 힙 손상 주제를 검색 한 결과 여러 가지를 시도해 보았습니다.

한 사람이 내 배열 tile_array에 대한 포인터가 프로그램이 delete[]에 도달 할 때까지 변경되었다고 제안했습니다. 하지만 두 번 확인했는데 포인터와 배열의 첫 번째 요소의 주소가 동일하게 유지됩니다.

다른 사람들의 게시물의 다른 포럼 답변은 대개 두 번 이상 배열을 삭제할 수 있다고 제안하지만 아직까지는 특정 배열에 delete[] 연산자가 사용 된 유일한 시간입니다.

+0

tile_array가 처음 설치되는 방식이 보이지 않지만 extern 및 global이므로 누군가 다른 사람도 삭제할 가능성이 있습니까? vs-debugger를 사용하여 할당량에 bp를 설정하고 데이터를 작성한 후에 BW (Break-On-Write)를 설정하고 다른 사람이 해당 데이터를 조회하는지 확인하십시오. 기회는 있습니다, 그들은 (또는 당신입니다). – WhozCraig

+0

StackOverflow에 오신 것을 환영합니다. 코드를 올바르게 포맷팅 해보십시오. 그것은 당신의 질문을 더 가독성있게 만들고 빠른 대답을 얻는 당신의 기회를 향상시킵니다. 탭 문자를 공백으로 대체하십시오. 코드 영역을 텍스트 영역에 붙여 넣고 모든 것을 선택하고'{}'문자와 함께 도구 모음 버튼을 사용하여 코드의 서식을 지정할 수 있습니다. 각 행을 4 자 이상으로 들여 쓰기하여 서식을 지정할 수도 있습니다. 입력하는 텍스트 영역 바로 아래의 거의 WYSYWIG 스타일로 서식을 지정할 때 미리 볼 수 있습니다. 감사. :-) –

답변

1

title_array에 대한 모든 액세스를 모른 채이 문제의 원인을 추측하기는 어렵습니다. 프로그램이 표시되는 메모리 손상으로 항상 원인이되는 것은 아닙니다.

확인할 사항은 extern 선언이 "tile * tile_array"이고 "tile tile_array []"타일이 아니라는 것입니다. 나는 이것이 매우 의심 스럽지만 extern과 배열을 다룰 때 나는이 실수가 몇몇 사람들을 물어 보았다고 보았다.

내가 할 수있는 또 다른 일은 그것을 삭제하고 선언 한 후에 tile_array를 NULL로 만드는 것입니다. 이 작업을 수행 할 때 문제가 사라지면 사실 너무 초기 삭제 (초기화되기 전에) 또는 너무 많은 삭제가있었습니다.

마지막으로 확인해야 할 점은 버퍼 오버/언더런이 없다는 것입니다. new [] 연산자는 delete [] 연산자가 배열의 크기를 알기 위해 사용하는 힙에 메타 데이터를 배치하여 메모리를 올바르게 정리합니다. 이 메타 데이터를 손상 시키면 힙이 손상 될 수 있습니다.

+0

미안하지만이 일로 돌아 가면 영원히 필요했습니다. 그러나 문제는 결국 버퍼 오버런이되었습니다. 나는 globalflags 프로그램에서 pageheap.exe를 설정하고 WinDbg을 사용하여 그것을 찾는 법을 배워야 만했지만, 나는 힙 손상을 일으킨 곳을 찾아 수정했다. 영원히 도와 줘서 고마워. –

+1

Microsoft의 Application Verifier를 사용하면 이러한 종류의 문제를 찾을 수있는 다른 도구를 사용할 수 있습니다. 매우 도움이된다. –