1.2.3 변형된 2차원 배열 동적 할당
앞에서 2차원 배열을 동적으로 생성하는 방법과 for 루프를 이용하여 픽셀 값을 참조하는 방법에 대해 설명하였다. 그러나 이 방법은 동적 할당된 전체 메모리 공간이 연속적이라고 100% 보장할 수가 없으며, 그렇기 때문에 영상 전체 픽셀을 1차원 배열처럼은 사용할 수 없다. 경우에 따라서는 2차원 영상을 1차원 데이터처럼 사용하는 것이 필요할 때가 있다.
그래서 이번에는 하나의 영상을 단일 메모리 블록으로 할당하고, 이를 2차원 배열과 동일한 방식으로 접근할 수 있는 방법에 대해 알아보려고 한다. 실제로 이 책에서 만드는 이미지 클래스에서는 이 방식으로 메모리 공간을 할당하여 사용할 것이다. 메모리를 할당하고 해제하는 방식은 앞서 알아본 방법과 조금 다르지만, 영상의 픽셀 데이터를 2차원 배열처럼 사용하는 방식은 완전히 동일하다. 다만 1차원 배열처럼도 사용할 수 있는 기능이 추가되었을 뿐이다. 먼저 새로운 메모리 할당 방법 코드를 살펴보자.
#include <memory.h> ... unsigned char** p; p = new unsigned char*[h]; p[0] = new unsigned char[w * h]; for (int i = 1; i < h; i+ +) p[i] = p[i - 1] + w; memset(p[0], 0, w * h);
위 코드를 보면 new 연산자를 이용하여 메모리를 할당하는 작업은 두 번만 발생한다. 일단 unsigned char* 타입의 메모리 공간을 h 크기만큼 동적 할당하여 p에 저장하였다. 그러므로 p[0]부터 p[h-1]까지는 모두 unsigned char* 타입을 저장할 수 있게 되었다. 이 중 맨 첫 번째 p[0]은 영상 전체 크기(w * h)에 해당하는 메모리 공간을 할당하여 그 주소를 받게 하였다. 나머지 p[1]부터 p[h-1]까지는 실질적인 new 연산자에 의한 동적 할당을 하지는 않고, 다만 p[0]이 가리키고 있는 영상 전체 메모리 영역의 특정 주소를 가리키도록 설정되어 있다. 이 부분에 대해서 그림을 보면서 자세히 이해해보자.