C언어에서는 코드 중간에 원하는 크기의 배열을 할당(동적할당)하는 것이 다른 언어들과 달리 쉽지 않다.
이에 C언어에서는 포인터를 이용하여 동적할당을 할 수 있는데, 다중 배열을 하려면 좀 머리가 아픈 경우가 많다.
이에, 저장용 겸으로 방법을 적어 본다.
보통 동적 할당을 하면 아래와 같은 예제들이 나온다.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
int x = 10; // 배열의 갯수
int* arr; // 배열
arr = (int*)malloc(sizeof(int) * x); // 배열 할당
for(i = 0; i < x; i++)
{
arr[i] = i; // 배열에 값 입력
printf("arr[%d] = %d\n", i, arr[i]); // 배열 값 출력
}
free(arr); // 배열 할당 해제
return 0;
}
하지만, 위 예제는 1차원 동적할당이며, 다중 배열의 경우는 보통 2차원까지만 아래와 같이 나온다.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j;
int x = 10; // 배열의 갯수
int y = 5;
int** arr; // 배열
arr = (int**)malloc(sizeof(int*) * y); // 2차원 배열 할당
for(i = 0; i < y; i++)
{
arr[i] = (int*)malloc(sizeof(int) * x);
for (j = 0; j < x; j++)
{
arr[i][j] = i * y + j; // 배열에 값 입력
printf("arr[%d][%d] = %d\n", i, j, arr[i][j]); // 배열 값 출력
}
}
for(i = 0; i < y; i++)
{
free(arr[i]);
}
free(arr); // 배열 할당 해제
return 0;
}
위 예제와 같이 한다면, 다차원이 될수록 배열 할당 해제시에 for문이 추가로 돌아야 하는 문제점과 각 배열의 주소 연속성을 보장하지 못하는 문제[각주:1]가 발생할 수 있다.
이에 아래와 같은 방법을 권장해본다.
참고로 아래의 방법은 포인터의 개념을 이용한 테크닉을 사용한 방법이다.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j, k;
int x = 20; // 배열의 갯수
int y = 10;
int z = 5;
int*** array; // 배열
array = (int***)malloc(z * sizeof(int**));
// 3차원 배열 할당 (5개), y 배열을 소유함
array[0] = (int**)malloc(z * y * sizeof(int*));
// 2차원 배열 할당 (5 * 10 = 50개), x 배열을 소유함
array[0][0] = (int*)calloc(z * y * x, sizeof(int));
// 1차원 배열 할당 및 0으로 초기화 (5 * 10 * 20 = 1000개)
for (i = 0; i < z; i++)
{
array[i] = array[0] + i * y;
// array[i]배열에 array[0]번째 배열의 주소에 y배열의 갯수만큼 띄어서 넣어준다.
// 이는 0번째를 제외한 나머지 배열은 주소가 없으므로 넣어주는 것이다.
for (j = 0; j < y; j++)
{
array[i][j] = array[0][0] + j * x + i * y * x;
// array[i][j]배열에 array[0][0]번째 배열의 주소에 i, j번째의 포인터 주소를 그 사이 배열의 갯수만큼 띄어서 넣어준다.
// 이역시 0번째를 제외한 나머지 배열은 주소가 없으므로 넣어주는 것이다.
for (k = 0; k < x; k++)
{
array[i][j][k] = j * x + i * y * x + k; // 배열에 값 입력
printf("array[%d][%d][%d] = %d\n", i, j, k, array[i][j][k]); // 배열 값 출력
}
}
}
free(arr[0][0]);
free(arr[0]);
free(arr); // 배열 할당 해제
return 0;
}
이 방식을 이용하면, 배열 할당 해제를 매우 쉽게 할 수 있으며, 실제 작업시 배열의 주소가 연속[각주:2]되어 있어 작업시 약간의 시간이익을 얻을 수 있다.
다만, 다차원 배열 할당시 차원이 올라갈수록 띄어야 하는 공간의 크기를 정확히 계산해야 하는 문제가 생기긴 한다.
위 예제의 최종 배열인 arr[5][10] 배열의 경우 arr[0][9]와 arr[1][0] 배열의 주소가 연속되지 않을 수 있다.
이는 시스템에서 해당 자료를 로딩하는데, 속도 지연이 생길 수 있다. [본문으로]
전체 배열 크기의 1차원 배열을 할당하여, 다차원 배열처럼 쓰는 방법이므로, 주소가 연속되어 있다. [본문으로]
'Do', or 'do not'.
There is no 'try'.
Since 2008.05.01