2차원 배열의 동적할당은 1차원 배열의 동적할당과 달리 생각해야 할 부분이 있다. 단순히 방법만 알아도 사용하는데 지장은 없지만, 복잡한 알고리즘내에서 계산을 하다 보면, 왜 기본이 중요한지 느끼게 된다. 그래서 기본을 설명하려 한다.
사전필요지식
2014/02/11 - [프로그래밍/C언어] - 이중포인터에 대한 이해 C언어
2013/11/28 - [프로그래밍/C언어] - C언어 포인터에 대한 이해(1)
2014/01/12 - [프로그래밍/C언어] - C언어 포인터에 대한 이해(2)
2014/01/13 - [프로그래밍/C언어] - C언어 포인터에 대한 이해(3)
2014/02/28 - [프로그래밍/C언어] - 동적배열 자료구조의 시작
반면 1차원 배열과 2차원 배열을 힙에 동적할당을 할 경우 1차원 배열은 연속적으로 늘어선 모양이지만 2차원 배열은 약간 다르다.
위 그림은 p[5][3]의 모양이다. 물론 힙에 할당이 된 모양이다.
참고로 p[5][3]이 스택에 할당된 모양은 다음과 같다.
2차원 배열이든 3차원 배열이든 스택에서의 할당은 위와같이 recursive 1차원 구조가 된다. 우리는 2차원 배열을 생각하면 행렬의 2차원적인 구조, 3차원배열은 큐브와 같은 3차원 배열을 떠올리지만, 컴퓨터가 할당하는 메모리는 언제나 1차원 구조로 할당된다.
우리는 첫번째 그림처럼 동적할당을 할 필요성이 있다.
p는 2중포인터로서 각 요소들은 실제로 값을 갖는 것이아니라, 2번째 그림에서처럼 그 값의 영역을 나타낸다. 다시말해 각 p의 요소들은 1차원 배열을 가리키는 포인터다.
- 먼저 2중포인터(p)를 선언하여 원하는 타입을 5개 담을수 있는 공간을 할당하고
- 각 요소(포인터) 또한 요소크기의 3개의 공간을 할당한다.
p할당, p의 각 요소들할당(p의 할당개수만큼 할당)
위 코드는 역행렬를 구하는 소스 중 행렬정보를 입력받는 부분이다.
참고 : *(ar+1)이 무엇을 뜻하는지 모른다면 위 링크의 포인터 부분부터 읽어보면 자세히 설명되어 있다.
메모리상의 구조를 보면 알겠지만, 힙에있는 정보는 모두 p를 기원으로 읽혀진다. 때문에 메모리에서 해제를 하려면 할당의 역순으로 해제를 해야한다.
만약 p만 해제를 했다면 그림1에서 p블럭(검은색) 만 해제가 되고 갈색 블럭들은 이름없는 고아가 되어 컴퓨터를 끌 때까지 메모리상에 상주하게 된다.
역행렬을 구하는 프로그램을 짜봤다면 알겠지만, 차원이 큰 행렬의 행렬식을 구할때 2차원부터 n차원까지의 행렬을 동적할당하기때문에 p만 해제를 했다면, 큰 메모리 누수가 일어날 수 있다.