동적 할당
프로그램 실행 중에 메모리를 필요할 때 직접 요청해서 사용하는 것이다.
- 보통 우리가 변수를 만들면 메모리 크기가 컴파일할 때 고정된다.
int arr[10];
그런데 실행할 때까지 몇 개가 필요할지 모를 수가 있다.
실행 중에 메모리를 필요한 만큼 "동적으로" 빌리는 것이다.
2. 동적 할당 함수
malloc 메모리를 '지정한 크기'만큼 빌려온다. (초기화 x)
calloc 메모리를 '지정한 크기' 만큼 빌려오면서 '0'으로 초기화 까지 해준다.
realloc 이미 빌린 메모리 크기를 '다시' 조정할 때 사용한다.
free 빌린 메모리를 반납 할 때 사용한다.
3. malloc 예제
#include <stdio.h>
#include <stdlib.H.
int main() {
int *p;
p = (int *)malloc(sizeof(int));
if (p == NULL) {
printf("메모리 할당 실패\n");
return 1;
}
*p = 10; // 빌린 메모리에 값을 저장한다.
printf("p가 가리키는 값: %d\n", *p);
free(p);
return 0;
}
malloc(sizeof(int)) -> int 하나 저장할 만큼 메모리를 빌려온다.
빌린 메모리는 포인터로 가리키고, 다 쓰면 free(p)로 반납을 한다.
주의할 점
malloc은 메모리 확보 실패할 수도 있다. -> 그래서 NULL 체크 꼭 해야한다.
빌린 메모리는 free() 로 꼭 반납해야 한다. -> 안하면 메모리 누수가 생기게 된다.
빌린 메모리는 배열처럼도 사용이 가능하다.
ex)
int *arr = (int *)malloc(sizeof(int) * 5);
arr[0] = 1;
arr[1] = 2;
예시로 코드를 한번 공부를 해봅시다
- 사용자에게 배열 크기를 입력받고 그 크기만큼 메모리를 동적 할당해서 배열에 값을 저장하고 출력한 뒤 메모리를 반납하는 프로그램을 만들어봅시다.
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr;
int n;
printf("몇 개의 정수를 저장할까요? ");
scanf("%d", &n);
arr = (int *)malloc(sizeof(int) * n);
if (arr == NULL) {
printf("메모리 할당 실패\n");
return 1;
}
// 배열에 값을 저장
for (int i = 0; i < n; i++) {
printf("%d번째 정수 입력: ", i + 1);
scanf("%d", &arr[i]);
}
printf("\n");
free(arr);
return 0;
}
몇 개 저장할지 사용자한테 물어보고, 그 크기만큼 malloc으로 메모리를 빌립니다. 배열처럼 arr[i]로 입력/출력을 받고, 다 끝나면 free(arr); 로 메모리를 반납합니다.
4.calloc
calloc는 malloc과 비슷하지만 차이가 있습니다.
malloc : 메모리 초기화 x , 매개변수 : 전체 크기 하나
calloc : 0으로 초기화 , 매개 변수 : 계수와 크기 둘 다 입력
calloc 기본 문법은 다음과 같습니다.
void *calloc(size_t num, size_t size);
num : 몇개 만들지
size : 하나당 크기 (바이트 단위)
즉, num * size 만큼 공간을 만들고 모두 0으로 초기화를 합니다.
calloc 예제
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr;
int n;
printf("저장할 정수 개수 입력: ");
scanf("%d", &n);
arr = (int *)calloc(n, sizeof(int));
if (arr == NULL) {
printf("메모리 할당 실패\n");
return 1;
}
printf("초기 배열 값들:\n");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr);
return 0;
}
calloc은 자동으로 0으로 초기화된다.
5. realloc
이미 동적 할당된 메모리를 "크기를 바꿀 때" 사용을 한다.
void *realloc(void *ptr, size_t size);
ptr : 기존에 할당한 메모리 주소
size : 새로 바꿀 크기
realloc 예제
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr;
int n;
printf("초기 정수 개수 입력: ");
scanf("%d", &n);
arr = (int *)malloc(sizeof(int) * n);
if (arr == NULL) {
printf("메모리 할당 실패\n");
return 1;
}
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
printf("\n배열 초기 값들:\n");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
printf("\n배열 크기를 늘립니다 추가할 개수 입력: ");
int add;
scanf("%d", &add(;
arr = (int *)realloc(arr, sizeof(int) * (n + add));
if (arr == NULL) {
printf("메모리 재할당 실패\n");
return 1;
}
for (int i = n; i < n + add; i++) {
arr[i] = (i + 1);
}
printf("\n크기 늘린 배열 값들:\n");
for (int i = 0; i < n + add; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr);
return 0;
}