문의한 코드는 삭제합니다.
위와 같이 소스코드를 작성해서 visual studio에서 실행했을 때 아래 사진처럼 정상적으로 뜨는 거 같은데 왜 심사문제에서 계속 오류라고 뜨나요?....
(도장_ 관리자에 의해 편집됨 - 원문 제출일 2018년 1월 25일, 목요일, 오후 12:56 )
제출하신 코드에 오류가 있습니다.
index 변수의 계산이 틀렸습니다. 제출한 코드는 다음과 같습니다.
int index = (x * PIXEL_SIZE) + (y * (height * PIXEL_SIZE)) + (y * padding);
올바른 코드는 다음과 같습니다.
int index = (x * PIXEL_SIZE) + (y * (width * PIXEL_SIZE)) + (padding * y);
따라서 테스트 이미지가 n*n으로 정사각형일 때는 프로그램이 동작하지만, 테스트 이미지가 m*n처럼 직사각형일 때는 오류가 발생하며 동작하지 않습니다. 즉, 문의한 코드에는 버그가 있고, 직사각형 이미지일 때는 우연의 일치로 동작하는 코드입니다.
첨부한 sample.bmp는 직사각형으로 만든 이미지입니다. 직접 테스트해보면 이해할 수 있을 것입니다.
심사 내부에서는 다양한 종류, 다양한 크기의 이미지 파일을 이용해 사용자가 제출한 코드를 심사합니다.
코딩도장 책하고 웹 페이지에는 (y * ( 세로크기 * 픽셀 크기))는 픽셀이 몇 번째 줄인지 계산하는 식이라고 나와있는데 width는 세로 크기가 아니라 가로 크기 아닌가요?... (y * (가로 크기 * 픽셀 크기))로 내용을 바꾸셔야 되는 거 아닌가요?...
Unit 81.3 픽셀을 아스키 문자로 저장하기를 참고하세요.
그림의 크기가 100*200이면
x * PIXEL_SIZE는 x의 위치를 찾아가기 위한 것입니다.
y * (width * PIXEL_SIZE)는 y의 위치를 찾아가기 위한 것입니다.
2차원 배열도 메모리에는 1차원으로 저장됩니다. 따라서 이와 같은 계산으로 (x, y)의 2차원 위치를 메모리에 있는 1차원의 위치로 계산해야 합니다.
1차원으로 계산한 위치 값은 index 변수에 저장합니다.
PIXEL_SIZE나 padding은 bmp 이미지 파일을 위한 처리입니다.
PIXEL_SIZE나 padding을 빼고 간단하게 생각해봅시다.
먼저 100 * 200인 이미지에서 해당 점의 위치(index)를 찾아봅시다.
먼저 (50, 0)의 위치를 찾아야 한다면
x = 50, y = 0입니다.
index = x + y * 100인데 y = 0이니
index = 50입니다.(1부터 센다고 가정합니다).
코드로 구현한다면 index = 49여야 겠죠(C 언어는 0부터 세니까요)
(50, 2)의 위치를 찾는다면
x = 50, y = 1입니다. 가로가 100이니 처음 100개 + 50을 해야 (50, 2)의 위치에 해당하겠죠.
index = 100 + 1 * 50 = 150
즉, 150번째 위치의 점이 (50, 2)에 해당합니다.
(50, 50)에 있는 점의 위치를 찾는다면
x = 50이고, y의 위치는 49 * 100일 겁니다.
따라서 index의 위치는
index = x + y * width이고, (50, 50)이면
index = 50 + 49 * 100 = 540번째 점의 위치가 될 겁니다.
이미지의 크기가 100*200이라고 했고, (100, 200)의 좌표이면
x = 100, y = 200이니
index = 100 + 199 * 100
으로 계산해야 합니다.
이미지의 크기가 100 * 200이고, (100, 200)의 위치를 읽으려면
index = 100 + 199 * 100 = 20000
즉, 마지막 점의 위치를 읽게 됩니다. C 언어는 0부터 세니까 실제로는 19999번째 점을 읽겠지요.
문의하신 코드처럼 width와 height를 바꾸면
(100, 200) 위치를 읽으려고 할 때
index = 100 + 200 * 200 = 40100
즉, 마지막 점의 위치가 40100번째에 있어야 합니다. 메모리는 20000까지 할당되어 있으니 영역을 벗어난 읽기가 발생합니다.
이게 Visual Studio에서 실행하면 read access violcation(읽기 접근 위반) 오류가 발생하는 이유입니다.
이해가 되었으면 좋겠습니다.
위의 예시에서 (50, 2)의 위치를 찾을려면 x = 50, y = 1이라고 하셨는데, 그렇게 되면 (50, 0)의 위치인 x = 50, y = 0 과 (50, 1)의 위치인 x = 50, y = 0 과 겹치게 됩니다. 이 관점에서 본다면 1부터 시작한다는 가정은 오히려 이해를 어렵게 만들 수 있다고 생각합니다.