38.4 입력한 크기만큼 메모리를 할당하여 포인터를 2차원 배열처럼 사용하기

이제 사용자가 입력한 만큼 메모리를 할당하여 포인터를 2차원 배열처럼 사용해보겠습니다.

pointer_scanf_like_two_dimensional_array.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>    // malloc, free 함수가 선언된 헤더 파일

int main()
{
    int row, col;

    scanf("%d %d", &row, &col);

    int **m = malloc(sizeof(int *) * row);   // 이중 포인터에 (int 포인터 크기 * row)만큼
                                             // 동적 메모리 할당. 배열의 세로

    for (int i = 0; i < row; i++)            // 세로 크기만큼 반복
    {
        m[i] = malloc(sizeof(int) * col);    // (int의 크기 * col)만큼 동적 메모리 할당. 배열의 가로
    }

    for (int i = 0; i < row; i++)    // 세로 크기만큼 반복
    {
        for (int j = 0; j < col; j++)    // 가로 크기만큼 반복
        {
            m[i][j] = i + j;             // 2차원 배열의 각 요소에 i + j 값을 할당
        }
    }

    for (int i = 0; i < row; i++)    // 세로 크기만큼 반복
    {
        for (int j = 0; j < col; j++)    // 가로 크기만큼 반복
        {
            printf("%d ", m[i][j]);      // 2차원 배열의 인덱스에 반복문의 변수 i, j를 지정
        }
        printf("\n");                // 가로 요소를 출력한 뒤 다음 줄로 넘어감
    }

    for (int i = 0; i < row; i++)    // 세로 크기만큼 반복
    {
        free(m[i]);                  // 2차원 배열의 가로 공간 메모리 해제
    }

    free(m);    // 2차원 배열의 세로 공간 메모리 해제

    return 0;
}

소스를 컴파일하여 실행한 뒤 4 5를 입력하고 엔터 키를 누르세요.

실행 결과

4 5 (입력)
0 1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7

먼저 scanf로 세로 크기와 가로 크기를 입력받습니다. 그리고 입력받은 세로 크기 변수 row를 활용하여 이중 포인터 m에 2차원 배열의 세로 공간 메모리를 할당합니다.

int **m = malloc(sizeof(int *) * row);   // 이중 포인터에 (int 포인터 크기 * row)만큼
                                         // 동적 메모리 할당. 배열의 세로

입력받은 가로 크기 변수 col을 활용하여 2차원 배열의 가로 공간 메모리를 할당합니다.

for (int i = 0; i < row; i++)            // 세로 크기만큼 반복
{
    m[i] = malloc(sizeof(int) * col);    // (int의 크기 * col)만큼 동적 메모리 할당. 배열의 가로
}

세로, 가로 크기가 고정되어 있지 않으므로 사용자에게 입력받은 row, col을 활용하여 세로와 가로를 반복하면서 값을 할당합니다. 여기서는 2차원 배열(메모리)의 각 요소에 ij를 더한 값을 할당하였습니다. 값 할당이 끝났으면 다시 세로와 가로를 반복하면서 2차원 배열의 값을 출력합니다.

for (int i = 0; i < row; i++)    // 세로 크기만큼 반복
{
    for (int j = 0; j < col; j++)    // 가로 크기만큼 반복
    {
        m[i][j] = i + j;             // 2차원 배열의 각 요소에 i + j 값을 할당
    }
}

for (int i = 0; i < row; i++)    // 세로 크기만큼 반복
{
    for (int j = 0; j < col; j++)    // 가로 크기만큼 반복
    {
        printf("%d ", m[i][j]);      // 2차원 배열의 인덱스에 반복문의 변수 i, j를 지정
    }
    printf("\n");                // 가로 요소를 출력한 뒤 다음 줄로 넘어감
}

마지막으로 입력받은 세로 크기만큼 반복하면서 가로 공간 메모리를 해제합니다. 그러고 나서 세로 공간 메모리를 해제합니다.

for (int i = 0; i < row; i++)    // 세로 크기만큼 반복
{
    free(m[i]);                  // 2차원 배열의 가로 공간 메모리 해제
}

free(m);    // 2차원 배열의 세로 공간 메모리 해제

지금까지 포인터와 배열을 응용하는 방법을 배웠는데 내용이 좀 어려웠습니다. 일단은 이런 것도 된다는 점만 알아두면 되고, 나중에 필요할 때 다시 돌아와서 찾아보면 됩니다.