1. 동적 메모리 관리
1) 정적 메모리 할당 (Static Memory Allocation)
- 정적 메모리 할당은 프로그램 실행 전에 메모리를 미리 할당하는 방식이다.
- 배열 등으로 미리 크기를 지정하면 해당 메모리는 프로그램 종료 시까지 고정된다.
- 고정된 크기 때문에 ⚠️ 메모리 낭비 또는 부족 문제가 발생할 수 있다.
2) 동적 메모리 할당 (Dynamic Memory Allocation)
- 동적 메모리 할당은 프로그램 실행 도중 필요에 따라 메모리를 요청하고 해제하는 방식이다.
- 메모리는 힙 영역에서 할당되며, stdlib.h에 정의된 malloc() 함수를 사용한다.
- malloc()은 할당에 실패하면 NULL을 반환한다. 따라서 ⚠️ NULL 체크는 필수이다.
int* s;
s = (int*)malloc(2 * sizeof(int)); // int 2개 분량 메모리 할당
s[0] = 10; // 또는 *s = 10;
s[1] = 11; // 또는 *(s + 1) = 11;
⭕ 할당된 메모리는 배열처럼 인덱스로 접근 가능하다.
3) 동적 메모리 반납
- 사용이 끝난 메모리는 반드시 free() 함수를 통해 반납해야 한다.
- 메모리를 해제하지 않으면 ❗ 메모리 누수(leak) 가 발생할 수 있다.
- 반납 후 해당 포인터를 재사용하거나 접근하면 정의되지 않은 동작을 유발한다.
free(s); // 메모리 반납
4) 동적 메모리 초기화: calloc()
- calloc() 함수는 메모리를 0으로 초기화한 상태로 할당한다.
- 인자에 요소 개수와 요소 크기를 각각 지정한다.
int* arr = (int*)calloc(5, sizeof(int)); // int 5개를 0으로 초기화하며 할당
5) 메모리 크기 변경: realloc()
- realloc() 함수는 이미 할당된 메모리 블록의 크기를 변경할 수 있다.
- 작게 재할당하면 ⚠️ 일부 데이터가 유실될 수 있다.
- 크게 재할당하면 기존 데이터를 유지하며 추가 메모리가 할당된다.
s = (int*)realloc(s, sizeof(int) * 5); // 기존 s 메모리를 5개 크기로 확장
✅ realloc()은 내부적으로 새로운 메모리 블록을 생성하고 복사하는 경우도 있으므로, 반드시 반환값을 확인해야 한다.
💻 예제 코드 - 동적 구조체 배열과 메모리 함수 사용
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[30];
int age;
} Person;
int main() {
int count;
printf("구조체 몇 개를 동적으로 할당할까요? ");
scanf_s("%d", &count);
// calloc으로 0으로 초기화된 구조체 배열 할당
Person* list = (Person*)calloc(count, sizeof(Person));
if (list == NULL) {
printf("메모리 할당 실패\n");
return 1;
}
// 사용자로부터 데이터 입력
for (int i = 0; i < count; i++) {
printf("[%d] 이름 입력: ", i + 1);
scanf_s("%s", list[i].name, (unsigned)_countof(list[i].name));
printf("[%d] 나이 입력: ", i + 1);
scanf_s("%d", &list[i].age);
}
// realloc으로 구조체 수 늘리기
list = (Person*)realloc(list, sizeof(Person) * (count + 2));
if (list == NULL) {
printf("메모리 재할당 실패\n");
return 1;
}
// 추가 입력
for (int i = count; i < count + 2; i++) {
printf("[%d] 이름 입력: ", i + 1);
scanf_s("%s", list[i].name, (unsigned)_countof(list[i].name));
printf("[%d] 나이 입력: ", i + 1);
scanf_s("%d", &list[i].age);
}
// 출력
printf("\n입력된 사람 정보:\n");
for (int i = 0; i < count + 2; i++) {
printf("이름: %s, 나이: %d\n", list[i].name, list[i].age);
}
free(list); // 메모리 해제
return 0;
}
🔍 예제 요약
- 사용자 입력에 따라 구조체 수를 동적으로 할당하였다.
- calloc()을 통해 초기화된 구조체 배열을 사용하였다.
- realloc()으로 구조체 수를 2개 더 늘렸다.
- free()로 메모리를 해제하였다.
✅ 마무리 정리
1️⃣ 정적 메모리는 프로그램 시작 시 고정된 크기로 할당된다.
2️⃣ 동적 메모리는 실행 중 malloc(), calloc() 등을 통해 필요에 따라 할당한다.
3️⃣ 사용 후에는 반드시 free()로 메모리를 반납해야 한다.
4️⃣ calloc()은 0으로 초기화된 메모리를 할당한다.
5️⃣ realloc()은 메모리 블록의 크기를 조절한다.
6️⃣ 동적 구조체 배열은 포인터와 sizeof를 활용하여 메모리를 관리한다.
7️⃣ NULL 반환 여부를 체크하여 메모리 할당 실패를 방지해야 한다.
'Language > C' 카테고리의 다른 글
| 📌 Chapter 17 - 선행처리기와 다중 소스 파일 - 선행처리기 (0) | 2025.06.24 |
|---|---|
| 📌 Chapter 16 - 동적 메모리와 연결 리스트 - 연결 리스트 (0) | 2025.06.23 |
| 📌 Chapter 15 - 스트림과 파일 입출력 (0) | 2025.06.21 |
| 📌 Chapter 14 - 구조체 - 함수, 중첩, 공용, 비트필드 (1) | 2025.06.20 |
| 📌 Chapter 14 - 구조체 - 배열 (0) | 2025.06.20 |