48.7 연습문제: 함수에서 행렬 만들기
다음 소스 코드를 완성하여 동적 메모리로 행렬을 생성하는 함수와 해제하는 함수를 만드세요.
practice_parameter_triple_pointer.c
#include <stdio.h> #include <stdlib.h> ①______________________________________ ... _______________________________________ ②______________________________________ ... _______________________________________ int main() { short **matrix; // m: 3, n: 3, 요소의 자료형 short allocMatrix(&matrix, 3, 3, sizeof(short)); matrix[0][2] = 10; matrix[1][1] = 20; printf("%d %d\n", matrix[0][2], matrix[1][1]); freeMatrix(&matrix, 3); return 0; }
정답
① void allocMatrix(void ***ptr, int m, int n, int elementSize) { *ptr = malloc(sizeof(void *) * m); for (int i = 0; i < m; i++) { (*ptr)[i] = malloc(elementSize * n); } } ② void freeMatrix(void ***ptr, int m) { for (int i = 0; i < m; i++) { free((*ptr)[i]); } free(*ptr); }
해설
short **matrix;와 같이 이중 포인터에 메모리를 할당하여 행렬을 만들어야 합니다. 여기서 allocMatrix(&m, 3, 3, sizeof(short));와 같이 matrix의 메모리 주소, 행렬 m, 행렬 n, 요소 크기를 넣어주었으므로 이 정보들을 이용해서 함수를 만들면 됩니다.
matrix가 이중 포인터이므로 메모리를 할당해서 가져오려면 allocMatrix의 매개변수를 삼중 포인터로 만듭니다. 행렬(2차원 배열)의 세로 공간에는 *ptr = malloc(sizeof(void *) * m);과 같이 *ptr을 역참조하여 메모리를 할당하면 됩니다. 여기서 주의할 점은 가로 공간 할당인데 *ptr[i]에 메모리를 할당하면 배열의 요소 ptr[i]를 역참조하여 메모리를 할당하게 됩니다. 따라서 (*ptr)[i]과 같이 ( ) (괄호)를 사용하여 ptr을 먼저 역참조한 뒤 [ ](대괄호)로 세로 공간의 배열 요소에 접근하여 메모리를 할당해야 합니다.
void allocMatrix(void ***ptr, int m, int n, int elementSize) { *ptr = malloc(sizeof(void *) * m); // ptr을 역참조한 뒤 메모리 할당 for (int i = 0; i < m; i++) { (*ptr)[i] = malloc(elementSize * n); // ptr을 먼저 역참조한 뒤 인덱스로 접근 } }
메모리 해제 함수는 할당 함수의 역순으로 만들어주면 됩니다. 해제는 할당과 달리 행(m) 값만 있으면 됩니다.