메모리 공간은 크게 4가지로 나뉩니다. Code영역, Data영역, Heap영역, Stack영역입니다. 그 중 Heap영역에만 뭐가 들어가는지 정확하게 알아보지 않았습니다.
한 번 예를 들어보겠습니다. 여러분이 함수에 값을 대입하여 계산한다고 생각하겠습니다.
void Sum(int a, int b) {
int n = a + b;
}
이런 함수가 있다고 가정할 때 n변수는 함수가 끝나면 없어집니다. 근데 n변수를 main함수에서도 계속 사용하고 싶습니다. 그럼 static 변수로 선언을 하면 되지만, 그것도 안쓸때는 메모리에서 지우고 싶은데 그것도 힘듭니다. 그럴 때 사용하는 것이 동적변수입니다.
사용자가 원할 때 메모리공간에 할당을 했다가, 사용자가 원할 때 메모리공간에서 삭제할 수 있습니다. 이러한 변수는 메모리공간의 Heap영역에 할당이 되고, 그 변수의 이름을 동적변수라고 합니다.

쉽게 말해서, 실행중에 메모리공간이 필요할 때 동적메모리 공간을 사용합니다. 동적메모리공간은 OS에게 요청해서 필요한 크기의 공간을 할당받습니다. 동적메모리공간은 사용한 후에 반드시 반납처리를 하셔야 합니다.
동적 할당하는 동적변수의 예시를 간단하게 보여드리겠습니다.
예시
#include <stdio.h>
#include <stdlib.h> //동적할당을 하기 위해서는 꼭 stdlib.h.를 include하셔야합니다.
int main() {
int count = 0;
printf("저장하실 정수의 갯수을 입력하세요: ");
scanf_s("%d", &count);
//동적메모리 할당
int* parray = (int*)malloc(sizeof(int) * count);
for (int i = 0; i < count; i++) {
parray[i] = i;
}
for (int i = 0; i < count; i++) {
printf("parray[%d] = %d\n", i, parray[i]);
}
printf("\n\nint형 저장공간을 double형 저장공간으로 변경\n");
double* pdarray = (double*)parray; //int* -> double*
for (int i = 0; i < count / 2; i++) {
pdarray[i] = i * 3.456; //double형 값을 저장
}
for (int i = 0; i < count / 2; i++) {
printf("pdarray[%d] = %lf\n", i, pdarray[i]);
}
free(pdarray); //동적메모리 공간을 반납처리(반드시 동적메모리 공간을 반납처리 해야함)
return 0;
}
결과
저장하실 정수의 갯수을 입력하세요: 4
parray[0] = 0
parray[1] = 1
parray[2] = 2
parray[3] = 3
int형 저장공간을 double형 저장공간으로 변경
pdarray[0] = 0.000000
pdarray[1] = 3.456000
C언어에서는 동적할당 함수의 종류가 크게 3가지 존재합니다. malloc, calloc, realloc함수입니다.
malloc함수는 가장 흔하게 쓰이는 동적할당 함수입니다.
형식은
int* ptr = (int*)malloc(sizeof(int) * count);
이고, ptr이 힙영역에 할당된 동적변수를 가리키는 포인터 변수가 됩니다.
calloc함수는 흔하게 쓰이지는 않는 동적할당 함수입니다. malloc함수와는 다른것은 size를 한번에 보내는 것이 아닌, *로 나누어진 size를 쪼개서 보냅니다.
형식은
int* ptr = (int*)calloc(count, sizeof(int));
입니다.
realloc함수는 이미 동적할당된 동적변수의 사이즈를 늘려주는 함수입니다. 특이한것은 원래있던자리에 추가로 동적할당하는것이 아닌 새로운 주소에 넓어진 범위만큼 할당해놓고 원래 있던 Data를 복사하여 저장합니다.
형식은
int* ptr = (int*)realloc(sizeof(int) * count * 2);
이고, realloc안에 사이즈는 최종크기를 말하는 것입니다. 즉, 원래크기보다 커야합니다.
간단하게 예시하나 보이겠습니다.
예시
#include <stdio.h>
#include <stdlib.h>
int main() {
int count = 10;
int* parray = (int*)malloc(sizeof(int) * count);
printf("\nmalloc으로 동적메모리 생성\n");
for (int i = 0; i < count; i++) {
printf("parray[%d] = %d\n", i, parray[i]);
}
free(parray);
parray = (int*)calloc(count, sizeof(int));
printf("\n\ncalloc으로 동적메모리 생성\n");
for (int i = 0; i < count; i++) {
printf("parray[%d] = %d\n", i, parray[i]);
}
printf("\n\nrealloc으로 동적메모리 재할당\n");
parray = realloc(parray, sizeof(int) * count * 2);
for (int i = 0; i < count * 2; i++) {
printf("parray[%d] = %d\n", i, parray[i]);
}
free(parray);
return 0;
}
결과
malloc으로 동적메모리 생성
parray[0] = -842150451
parray[1] = -842150451
parray[2] = -842150451
parray[3] = -842150451
parray[4] = -842150451
parray[5] = -842150451
parray[6] = -842150451
parray[7] = -842150451
parray[8] = -842150451
parray[9] = -842150451
calloc으로 동적메모리 생성
parray[0] = 0
parray[1] = 0
parray[2] = 0
parray[3] = 0
parray[4] = 0
parray[5] = 0
parray[6] = 0
parray[7] = 0
parray[8] = 0
parray[9] = 0
realloc으로 동적메모리 재할당
parray[0] = 0
parray[1] = 0
parray[2] = 0
parray[3] = 0
parray[4] = 0
parray[5] = 0
parray[6] = 0
parray[7] = 0
parray[8] = 0
parray[9] = 0
parray[10] = -842150451
parray[11] = -842150451
parray[12] = -842150451
parray[13] = -842150451
parray[14] = -842150451
parray[15] = -842150451
parray[16] = -842150451
parray[17] = -842150451
parray[18] = -842150451
parray[19] = -842150451
malloc과 realloc으로 추가한 변수에는 초기화를 안했기 때문에, 쓰레기값이 저장된것을 볼 수 있습니다.
문자열 동적할당은 int형이 char형으로만 바뀌면 됩니다.
예시
#include <stdio.h>
#include <stdlib.h>
int main() {
int count = 0;
int input = 0;
printf("입력하실 문자의 갯수를 입력하세요: ");
scanf_s("%d", &count);
char* pstr = (char*)malloc(sizeof(char) * count + 1); //동적 메모리 공간 할당
int i = 0;
for (i = 0; i < count; i++) {
printf("%d번째 문자를 입력하세요: ", i + 1);
scanf_s("%*c%c", &input);
pstr[i] = input;
}
pstr[i] = '\0';
printf("입력하신 문자열은 %s입니다.\n", pstr);
free(pstr); //동적메모리 할당 해제
return 0;
}
결과
입력하실 문자의 갯수를 입력하세요: 7
1번째 문자를 입력하세요: M
2번째 문자를 입력하세요: O
3번째 문자를 입력하세요: N
4번째 문자를 입력하세요: S
5번째 문자를 입력하세요: T
6번째 문자를 입력하세요: E
7번째 문자를 입력하세요: R
입력하신 문자열은 MONSTER입니다.
구구단 단수를 입력받고 동적메모리를 할당 받은 후, 해당 단수를 동적메모리에 저장하고 출력하세요.
코드
#include <stdio.h>
#include <stdlib.h>
int main() {
int dan = 0;
printf("단수를 입력하세요: ");
scanf_s("%d", &dan);
if (dan < 2 || dan > 9) {
printf("단수를 잘못 입력하셨습니다.\n");
}
else {
int* arr = (int*)malloc(sizeof(int) * 9);
for (int i = 0; i < 9; i++) {
arr[i] = dan * (i + 1);
}
printf("----%d단----\n", dan);
for (int i = 0; i < 9; i++) {
printf("%d x %d = %d\n", dan, i + 1, arr[i]);
}
free(arr);
}
return 0;
}
결과
단수를 입력하세요: 4
----4단----
4 x 1 = 4
4 x 2 = 8
4 x 3 = 12
4 x 4 = 16
4 x 5 = 20
4 x 6 = 24
4 x 7 = 28
4 x 8 = 32
4 x 9 = 36
단수를 입력하세요: 8
----8단----
8 x 1 = 8
8 x 2 = 16
8 x 3 = 24
8 x 4 = 32
8 x 5 = 40
8 x 6 = 48
8 x 7 = 56
8 x 8 = 64
8 x 9 = 72
단수를 입력하세요: 10
단수를 잘못 입력하셨습니다.