프로그래밍/C
C언어 [C언어 2차원 배열 동적할당]
프로앱등이
2020. 5. 3. 20:35
2차원 배열 동적할당
2차원 배열을 동적 할당하기 위해선 조금 다른 방법을 사용해야 한다.
1. 배열 포인터를 사용하여 동적 할당 하는 방법
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <stdio.h> #include <stdlib.h> //2차원 배열 동적 메모리 할당 int main() { int (*ptr)[3]; //동적 메모리 공간을 할당 받기 위한 포인터 배열 int i,n,j; printf("몇행을 할당 하시겠습니까? "); scanf("%d",&n); ptr = (int(*)[3])malloc(sizeof(int) * 3 * n); // 2차원 배열을 처리하기 위해 수식 표현 if(ptr == NULL) // 동적할당 실패시 NULL 리턴 { printf("동적 할당 실패"); } for(i;i<n;i++) { for(j=0;j<3;j++) { ptr[i][j]=i; printf("%d",ptr[i][j]); } printf("\n"); } free(ptr); } 실행결과 몇행을 할당 하시겠습니까? 5 000 111 222 333 444 |
2. 이중 포인터를 사용한 동적 할당 방법
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #include <stdio.h> #include <stdlib.h> int main() { int n=3; //행 int m=4; //열 int i,j; int** p; p = (int**)malloc(sizeof(int*) * n); //행을 의미한다 if(p == NULL) printf("동적할당 실패"); for(i=0;i<n;i++) { p[i] = (int*)malloc(sizeof(int) * m); //열을 의미한다 } for(i=0;i<n;i++) { for(j=0;j<m;j++) { p[i][j] = j+10; } } for(i=0;i<n;i++) { for(j=0;j<m;j++) { printf("%d",p[i][j]); } printf("\n"); } for(i=0; i<n; i++) { free(p[i]); } free(p); } 실행결과 [10][11][12][13] [10][11][12][13] [10][11][12][13] |
위의 이중 포인터를 사용한 방법이 가장 일반적이다 그리고 위의 방법을 사용해야 동적할당을 하는 의미가 있다.
3. 이중 포인터를 사용한 동적 할당 포인터 변수 함수의 매개변수로 전달
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include<stdio.h> #include<stdlib.h> int height=6; int width=8; int sub(int*** arr); //삼중 포인터로 인자 받음 int sub(int*** arr) //Call By Reference이기 때문에 삼중 포인터를 사용한다. { int i,j; for(i=0; i<height; i++) { for(j=0; j<width; j++) { (*arr)[i][j] = i+10; } } for(i=0; i<height; i++) { for(j=0; j<width; j++) { printf("%3d", (*arr)[i][j]); } printf("\n"); } for(i=0; i<height; i++) { free((*arr)[i]); } free(*arr); return 0; } int main(void) { int **arr; int i,j; arr=(int**)malloc(sizeof(int*)*height); //행을 만든다고 생각하자 for(i=0; i<height; i++) { arr[i] = (int*)malloc(sizeof(int)*width); //열을 만든다고 생각하자 } sub(&arr); return 0; } |
이중 포인터를 사용하였기 때문에 함수의 형식매개변수 에서 전달 받을때에는 ***삼중 포인터를 사용해야 한다 (Call By Reference 방식일경우)
(Call By Value) 일 경우에는 **이중 포인터를 사용하여 받을수 있다.
1 | p = (int**)malloc(sizeof(int*) * n); //2차원 배열 동적할당 -> 행을 의미한다고 할수 있다. for(i=0;i<n;i++) { p[i] = (int*)malloc(sizeof(int) * m); //열을 의미한다 } |
사실 위의 코드가 이해하기 힘들다 이중 포인터를 왜 써야 할까 라는 생각이 들수 있다 기존에 우리가 1차원 배열을 동적할당 할 때에는
1 | p = (int()malloc(sizeof(int) * n); //1차원 배열 동적할당 |
위와 같은 형태를 사용하였다 이 말은 4byte공간 n개를 만들겠다는 뜻이다. 하지만 2차원 배열은 행과,열이라는 표기로 나누게 된다

즉, 2차원 배열은 int의 주소를 넘겨주는것이다 sizeof(int*) 뜻은 포인터 변수의 주소를 n개 만들겠다는 뜻이다.
그래서 int의 공간 n개를 만들고 거기의 시작주소를 넘겨주기 때문에 **p 이중포인터로 받는것이다.
그리고 n개의 int공간을 만들고 해당 주소를 넘겨 받으면 또 그 공간에 우리가 부르는 '열' 이라는 공간을 만드는것이다.
그림을 잘 그리진 못했지만 위와 같은 형태라고 생각하면 이해가 편할것이다. 각 문법이 의미하는 것을 도식화 하였다.