2015-01-06 2 views
-1

그래서 내가있어 코드 :왜 이것이 힙 손상을 수정합니까?

float **array = new float*[width + 1]; //old line was '= new float*[width]' 

    //Create dynamic 2D array 
    for (int i = 0; i < width; ++i) { 
     array[i] = new float[height + 1]; //old line was '= new float[height]' 
    } 

    //Hardcode 2D array for testing 
    for (int i = 0; i < height; ++i) { 
     for (int j = 0; j < width; ++j) { 
      array[i][j] = i + j; 
     } 
    } 

    //deallocate heap memory 
    for (int i = 0; i < width; ++i) { 
     delete [] array[i]; //Where corrupted memory error used to be 
    } 
    delete [] array; 

(공식적으로, 나는 메모리를 하나의 블록을 할당하는 것이 더 효율적이 될 것입니다 알고,하지만 난 결코 이해하지 못할 것입니다 과학자들과 긴밀히 이유/방법을 작동 서버에서 실행되기 때문에 상사가 선호한다고 말합니다.)

제 질문은 왜 + 1/width + 1 높이가 손상된 메모리 문제를 해결합니까? 나는 여분의 공간이 널 터미네이터를위한 것이지만, 왜 그것이 필요한지 알고있다. 왜 높이와 너비가 같을 때 작동합니까?

SOLN : 내 배열을 채우면서 뒤로/내 높이를 가졌습니다 ... -.-; NPE에 감사드립니다. 메모리 오류 을 발생한 위치

delete [] array[i]; //Where corrupted memory error used to be 

이되지 않습니다 :

+4

프로그램에 다른 오류가 있습니다. 이것은 아닙니다. –

+1

버퍼에 1을 추가하면 오류를 없애고 어딘가에 1 오류가 발생할 수 있습니다. 귀하의 예는 불완전하지만 우리는 더 이상의 조언을 드릴 수는 없습니다. 또한 ... 널 터미네이터가 필요한 이유를 잘 모르겠다. 'float' 배열은 확실히 그렇지 않습니다. –

+1

'내 질문에 왜 높이 + 1/너비 + 1이 손상된 메모리 문제를 해결합니까? ' 당신이 한 일은 부패 버그를 프로그램의 다른 곳으로 옮기는 것이 었습니다. – PaulMcKenzie

답변

3

대한 다음 설명은 붉은 청어입니다. 이것은 이 발견되어이 발견되었습니다 (C++ 런타임 기준). 런타임은 this sort of errors을 감지 할 의무가 없으므로 어떤 방식 으로든 도움이됩니다. :-)

코드 부분에 보이지 않는 코드 부분에 buffer overrun (반복문에 하나씩 잘못된 오류가 있음)이 있습니다.

코드를 검토하여 찾을 수없는 경우 GCC에서 Valgrind 또는 -fsanitize=address을 사용해보십시오.

편집 : 당신이 질문에 추가 한 코드 문제 :

//Hardcode 2D array for testing 
for (int i = 0; i < height; ++i) { 
    for (int j = 0; j < width; ++j) { 
     array[i][j] = i + j; 
    } 
} 

widthheight (또는, 동등하게, ij) 길을 잘못 라운드 가지고 있다는 것입니다. width == height이 아니면 코드에 undefined behaviour이 있습니다.

+0

또는 GCC에서'-fsanitize = address' 옵션을 시도해보십시오. –

+0

@ Hi-Angel : 오, 좋았어,'-fsanitize = address'에 대해 몰랐어. – NPE

+0

은 문서를 찾을 수 없으므로 여기에 유의하겠습니다 :이 옵션은 4.9 릴리스 이후에 나타났습니다. 이 옵션이 -fmudflap의 다른 옵션이되기 전에, 나는 마지막으로 시도하지 않았기 때문에 그것에 대해 말할 수 없었다. 그러나 주소 살균기는 실제로 멋진 점입니다. 오류를 출력하기 위해 인쇄 할 때 문법 색으로 표시됩니다. : –

1

높이와 무게를 높이 + 1 및 무게 + 1로 변경하면 아마도 충분하지 않을 수 있습니다. 게시 한 코드가 높이와 무게에 맞습니다.

이것은 코드의 다른 부분에서 무언가가 해당 배열의 끝 부분을 지나쳐 쓰기 쉽다는 것을 의미하며, 이러한 배열을 성장 시키면 배열 대신 오류가있는 코드가 충돌 대신 작성됩니다. 문제를 해결하지 못했지만 방금 숨겼습니다.

OS가 힙 손상을 감지하는 방법의 몇 가지 제한 때문에 코드가 실제로 delete []에서 충돌했습니다. 힙에 대한 off-by-one 오류는 new/delete/malloc/free에 대한 다음 호출에서 감지됩니다. 실제로 발생하지는 않습니다.

프로그램이 포인터로 불법적 인 일을하는시기와 위치를 정확하게 알고 싶다면 Valgrind와 같은 도구를 사용할 수 있습니다.

0

코드를 수정하지 않았습니다. 현재 수행중인 작업은 새 코드로 실행 파일을 변경하여 손상 버그를 프로그램의 다른 부분으로 옮기는 것입니다.

한 가지는 당신이 하지 어떻게해야 - 당신이 말하는 + 1으로 "작동"사람에 프로그램을 변경 한 다음 그것을 허용하지 않습니다. 버그를 진단하기가 어렵지만이 경로를 지정하지 않으면 유혹을받을 수 있습니다.

수행해야하는 작업은 작동하지 않는 버전으로 돌아가서 문제를 해결하는 것입니다. "픽스"란 픽스가 무엇을하는지, 왜 픽스가 문제인지 등을 설명 할 수 있음을 의미합니다.

관련 문제