C에서 1,2 차원 배열에 동적으로 메모리를 할당하는 법

정글일지 20

C에서 1,2차원 배열에 동적으로 메모리를 할당하는 법

우리는 C에서 정적, 동적 배열을 모두 만들 수 있다. 이러한 배열은 1차원 혹은 다차원이다. 정적으로 할당된 배열 문제는 우리가 배열의 크기를 구체화해야 한다는 것이다. 그래서 문제는 앞으로 필요한 배열의 크기를 모를때 발생한다.

우리는 이 문제를 동적 메모리 할당으로 해결할 수 있다. 동적 메모리 할당의 이점은 실행동안 힙에 할당된다는 것이다. C 언어는 실행 중 메모리를 요청하는 함수들을 제공한다.

아래 프로그램에서, 1차원과 2차원 메모리에 동적 메모리를 할당하기 위해 malloc 함수를 사용할 것이다.

C에서 malloc의 문법

void * malloc (size_t size);

한도

크기 ==> 바이트내에서 메모리 블록의 크기

반환 값

할당된 메모리를 가리키는 포인터를 반환한다. 만약 메모리가 충분하지 않으면 NULL을 반환한다.

C에서 동적 메모리 할당을 사용한 1차원 배열

아래 예시에서, 정수에 대한 포인터를 만들고 힙 메모리에 지정했다(assign). 메모리에 포인터가 성공적으로 임명되면, 우리는 이 포인터를 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
#include <stdio.h>
#include <stdlib.h>
#define FAIL 1
#define TRUE 0
int main(int argc, char *argv[])
{
    int *piBuffer = NULL; //pointer to integer
    int nBlock = 0; //Variable store number of block
    int iLoop = 0; //Variable for looping
    printf("\nEnter the number of block = ");
    scanf("%d",&nBlock); //Get input for number of block
    piBuffer = (int *)malloc(nBlock * sizeof(int));
    //Check memory validity
    if(piBuffer == NULL)
    {
        return FAIL;
    }
    //copy iLoop to each block of 1D Array
    for (iLoop =0; iLoop < nBlock; iLoop++)
    {
        piBuffer[iLoop] = iLoop;
    }
    //Print the copy data
    for (iLoop =0; iLoop < nBlock; iLoop++)
    {
        printf("\npcBuffer[%d] = %d\n", iLoop,piBuffer[iLoop]);
    }
    // free allocated memory
    free(piBuffer);
    return TRUE;
}

동적 메모리 할당을 사용한 2차원 배열

C언어에서, 1차원 배열처럼 실행 중에동적 메모리 할당을 이용하여 2차원 배열을 만들 수 있다. 아래는 포인터를 사용하여 2차원 배열을 만드는 대략적인 방식이다.

C에서 포인터를 가리키는 포인터를 활용하여 2차원 동적 배열 만드는 방법

  • 포인터를 가리키는 포인터를 만들고 malloc()을 사용하여 행(row)을 위한 메모리를 할당한다.

    1
    2
    
    int ** piBuffer = NULL;
    piBuffer = malloc( nrows * sizeof(int *));
    
  • malloc()을 사용하여 각 행열을 위한 메모리를 할당한다.

1
2
3
4
for(i = 0; i < nrows; i++)
{
	piBuffer[i] = malloc( ncolumns * sizeof(int));
}
  • 만약 각 행이 같은 수의 열을 가지지 않았다면, 각 행에 개별적으로 메모리를 할당한다.
1
2
3
4
piBuffer[0] = malloc( ncolumns * sizeof(int));
piBuffer[1] = malloc( ncolumns * sizeof(int));

piBuffer[n] = malloc( ncolumns * sizeof(int));

각 행이 같은 수의 열을 가질때

우리는 각각 행과 열을 위해 malloc 함수를 두 번 호출한다.

각각의 행의 모든 위치는 인접한 메모리이지만 힙에서 모든 행이 인접한 메모리에 있어야 하는 것은 아니다.(Every location in each row is a contiguous memory but it is not necessary every row at contiguous memory in heap.)

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <stdlib.h>
#define FAIL 1
//Free Allocated memory
void freeAllocatedMemory(int **piBuffer, int nRow)
{
    int iRow = 0;
    for (iRow =0; iRow < nRow; iRow++)
    {
        free(piBuffer[iRow]); // free allocated memory
    }
    free(piBuffer);
}
int main(int argc, char *argv[])
{
    int **piBuffer = NULL; //pointer to pointer
    int nRow = 0; //variable store number of Row
    int nColumn = 0; //variable store number of Row
    int iRow = 0; //Variable for looping Row
    int iCol = 0; //Variable for looping column
    printf("\nEnter the number of Row = ");
    scanf("%d",&nRow); //Get input for number of Row
    printf("\nEnter the number of Column = ");
    scanf("%d",&nColumn); //Get input for number of Column
    //Allocate memory for row
    piBuffer = (int **)malloc(nRow * sizeof(int*));
    //Check memory validity
    if(piBuffer == NULL)
    {
        return FAIL;
    }
    //Allocate memory for column
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        piBuffer[iRow] = (int *)malloc(nColumn * sizeof(int));
        //Check memory validity
        if(piBuffer[iRow] == NULL)
        {
            freeAllocatedMemory(piBuffer,iRow);
            return FAIL;
        }
    }
    //Copy the data in 2d Array
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        for (iCol =0 ; iCol < nColumn ; iCol++)
        {
            piBuffer[iRow][iCol] = 3;
        }
    }
    //Print the content of 2D array
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        for (iCol =0 ; iCol < nColumn ; iCol++)
        {
            printf("\npiBuffer[%d][%d] = %d\n",iRow, iCol,piBuffer[iRow][iCol]);
        }
    }
    freeAllocatedMemory(piBuffer,nRow);
    return 0;
}

각 행이 다른 수의 열을 가질 때

우린 C에서 동적 메모리 할당을 이용하여 사각형이 아닌 2차원 배열을 만들수도 있다. 각 행마다 분명히 malloc을 호출해야 한다. 각 행에서 열의 숫자는 그들의 행의 index값 + 1과 같다. 예를 들어, 0번째 행은 1개의 열을 1번째 행은 2개의 열을 가진다. 반복문을 이용하여 malloc함수를 호출한다.

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
48
49
50
51
52
53
54
55
56
57
58
59
#include <stdio.h>
#include <stdlib.h>
#define FAIL 1
//Free Allocated memory
void freeAllocatedMemory(int **piBuffer, int nRow)
{
    int iRow = 0;
    for (iRow =0; iRow < nRow; iRow++)
    {
        free(piBuffer[iRow]); // free allocated memory
    }
    free(piBuffer);
}
int main(int argc, char *argv[])
{
    int **piBuffer = NULL; //pointer to pointer
    int nRow = 0; //variable store number of Row
    int iRow = 0; //Variable for looping Row
    int iCol = 0; //Variable for looping column
    printf("\nEnter the number of Row = ");
    scanf("%d",&nRow); //Get input for number of Row
    //Allocate memory for row
    piBuffer = (int **)malloc(nRow * sizeof(int*));
    //Check memory validity
    if(piBuffer == NULL)
    {
        return FAIL;
    }
    //Allocate memory for column
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        piBuffer[iRow] = (int *)malloc((iRow+1) * sizeof(int));
        //Check memory validity
        if(piBuffer[iRow] == NULL)
        {
            freeAllocatedMemory(piBuffer,iRow);
            return FAIL;
        }
    }
    //Copy the data in 2d Array
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        for (iCol =0 ; iCol <= iRow ; iCol++)
        {
            piBuffer[iRow][iCol] = 27;
        }
    }
    //Display the stored data
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        for (iCol =0 ; iCol <= iRow ; iCol++)
        {
            printf("\npiBuffer[%d][%d] = %d\n",iRow, iCol,piBuffer[iRow][iCol]);
        }
    }
    //Free Allocated memory
    freeAllocatedMemory(piBuffer,iRow);
    return 0;
}

C에서 단일 포인터를 사용한 동적 2차원 배열

이 방법을 사용하여 우리는 메모리를 저장할 수 있다. 우린 한 개의 malloc을 실행하여 큰 1차원 배열을 만들 수 있다. 만들오ㅓ진 1차원 배열위에 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
#include <stdio.h>
#include <stdlib.h>
#define FAIL 1
int main(int argc, char *argv[])
{
    int *piBuffer = NULL; //pointer to integer
    int nRow = 0; //variable store number of Row
    int nColumn = 0; //variable store number of Row
    int iRow = 0; //Variable for looping Row
    int iCol = 0; //Variable for looping column
    printf("\nEnter the number of Row = ");
    scanf("%d",&nRow); //Get input for number of Row
    printf("\nEnter the number of Column = ");
    scanf("%d",&nColumn); //Get input for number of Column
    //Allocate memory for row
    piBuffer = (int *)malloc(nRow * nColumn * sizeof(int));
    //Check memory validity
    if(piBuffer == NULL)
    {
        return FAIL;
    }
    //Copy 5 in 2d Array
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        for (iCol =0 ; iCol < nColumn ; iCol++)
        {
            piBuffer[iRow * nColumn + iCol] = 5;
        }
    }
    //Print the content of 2D array
    for (iRow =0 ; iRow < nRow ; iRow++)
    {
        for (iCol =0 ; iCol < nColumn ; iCol++)
        {
            printf("\npiBuffer[%d][%d] = %d\n",iRow, iCol,piBuffer[iRow * nColumn + iCol]);
        }
    }

    //free the allocated memory
    free(piBuffer);

    return 0;
}