Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
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
Tags more
Archives
Today
Total
관리 메뉴

Hello Security World

C언어 [C언어 2차원 배열 동적할당] 본문

프로그래밍/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 == NULLprintf("동적할당 실패");
    
    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
= (int**)malloc(sizeof(int** n); //2차원 배열 동적할당 -> 행을 의미한다고 할수 있다. for(i=0;i<n;i++) { p[i] = (int*)malloc(sizeof(int) * m); //열을 의미한다 }
 

사실 위의 코드가 이해하기 힘들다 이중 포인터를 왜 써야 할까 라는 생각이 들수 있다 기존에 우리가 1차원 배열을 동적할당 할 때에는

1
= (int()malloc(sizeof(int* n); //1차원 배열 동적할당
 

위와 같은 형태를 사용하였다 이 말은 4byte공간 n개를 만들겠다는 뜻이다. 하지만 2차원 배열은 행과,열이라는 표기로 나누게 된다

 

 

즉, 2차원 배열은 int의 주소를 넘겨주는것이다 sizeof(int*) 뜻은 포인터 변수의 주소를 n개 만들겠다는 뜻이다.

그래서 int의 공간 n개를 만들고 거기의 시작주소를 넘겨주기 때문에 **p 이중포인터로 받는것이다.

그리고 n개의 int공간을 만들고 해당 주소를 넘겨 받으면 또 그 공간에 우리가 부르는 '열' 이라는 공간을 만드는것이다.

그림을 잘 그리진 못했지만 위와 같은 형태라고 생각하면 이해가 편할것이다. 각 문법이 의미하는 것을 도식화 하였다.