*메모리 동적할당


지역변수는 stack에 저장되어 선언할 수 있는 메모리 크기를 제한합니다.(1Mbyte)

할당한 메모리를 Heap에 저장하여 stack보다 큰 메모리를 할당할 수 있습니다.

지역변수라 사용여부와 관계없이 종료될 때까지만 메모리를 점유합니다.

메모리사용시점과 소멸시점을 정할 수 있기 때문에 효율적인 메모리 사용이 가능합니다.


메모리 크기를 변경하기 위해서는 해당 프로그램을 재컴파일 해야하며, 이 때 실행 중 사용할 메모리 크기를 정할 수 있습니다.


  포인터를 이용하여 실행중 가변적인 크기의 메모리를 할당하고 해제할 수 있는데 이를 메모리 동적 할당이라고 합니다.


1
2
3
4
5
6
7
#include <stdlib.h>
 
//메모리 동적할당
void *malloc (size_t, size);
 
//메모리 해제
void free(void *memblock);

Malloc 함수는 할당된 메모리 주소의 값을 반환할 때 정해진 변위가 없다는 의미로 void * 형을 반환하기 대문에 포인터 변수로 주소를 받을 때에는 캐스팅을 해야합니다.

사용 후 free 함수를 이용해 반드시 메모리를 해제해 주어야 합니다.

Heap에 할당된 메모리는 stack에 할당된 메모리와 달리 스스로 해제되지 않습니다.


VMM이 포인터 유효성 검사를 실시하므로 배열이 포인터보다 속도가 빠릅니다.


1
2
3
4
5
6
//heap 영역에 1byte 메모리 공간을 확보하고
//시작주소를 char * 타입으로 변환 저장
char *p = (char *)malloc(1);
 
//할당한 메모리 해제
free(p);

  메모리 크기를 비슷하게 구성(4byte) 하거나 크게 할당받은 뒤 구역 재설정을 실시하면 속도를 빠르게 할 수 있습니다.


  동적할당을 할 때 하나의 데이터 형을 저장할 수 있는 크기가 아닌 배열처럼 여러개의 데이터형을 저장할 수 있는 크기의 메모리도 할당이 가능합니다.


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
int i;
char *p1, *p2;
 
//char 크기만큼 메모리 할당
p1 = (char *)malloc(sizeof(char));
 
//5개의 항목을 가진 char 배열 크기만큼의 메모리 할당
p2 = (char *)malloc(sizeof(char)*5);
 
*p1 = 0;
 
for(i = 0; i < 5; i++) *(p2+i) = i;
 
void main() {
    int *p, count, j, sum = 0;
    printf("숫자 입력: ");
    scanf("%d", &count);
    p = (int *)malloc(sizeof(int)*count);
for {
...
}
printf(...);
 
free(p);
 
}


1
2
3
4
5
6
7
8
9
10
11
12
//Worst case : 직접적인 형태의 메모리 할당
int *p = (int *)malloc(sizeof(int)*5);
int **pp = &p;
free(p);
 
//worse case: 배열포인터를 이용한 메모리 할당
int *p_data[3];
for(i = 0; i < 3; i++){
    p_data[i] = (int *)malloc(sizeof(int)*5);
}
 
for(i = 0; i < 3; i++) free(p_data[i]);

두번째 케이스를 잠시 보겠습니다.

int *p_data[3]; -> 배열 하나에 포인터가 세개 12byte=3*4byte

int (*p_data[3]); -> 포인터 한 개가 가리키는 변위의 크기: 4byte 1*12byte


아래는 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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
 
 
void EnterToContinue(){
    int c;
    printf("press ENTER to continue..");
    fflush(stdin);
    do c = getchar();
    while (c != '\n');
}
 
int main(void) {
    //array dimensions
    int x, y, z;
    //array iterators
    int k, j, i;
    //integer for count, pause
    int count = 0, pause = 0;
 
 
    //ask size of array
    printf("Determine the number of X : ");
    scanf_s("%d", &x);
    printf("Determine the number of Y : ");
    scanf_s("%d", &y);
    printf("Determine the number of Z : ");
    scanf_s("%d", &z);
 
    //make array
    int ***arr = (int ***)malloc(z*sizeof(int**));
    for (i = 0; i < z; i++){
        arr[i] = (int **)malloc(y*sizeof(int*));
        for (j = 0; j < y; j++){
            arr[i][j] = (int*)malloc(x*sizeof(int));
            for (k = 0; k < x; k++){
                arr[i][j][k] = count;
                count++;
            }
        }
    }
 
 
    //show array
    for (i = 0; i < z; i++){
        printf("    z= %d\n", i);
        for (j = 0; j < y; j++){
            printf("y= %d   ", j);
            for (k = 0; k < x; k++){
                printf("%2d ",arr[i][j][k]);
            }
            printf("\n");
        }
        printf("\n");
    }
     
     
    //deallocates a memory block
    for (i = 0; i < x; i++){
        for (j = 0; j < y; j++){
            free(arr[i][j]);
        }
        free(arr[i]);
    }
    free(arr);
 
    EnterToContinue();
}


+ Recent posts