고급 C 프로그래밍 – 동적 메모리 할당과 관리 – 2편: 동적 할당된 메모리 사용하기
안녕하세요, 프로그래머 여러분! 😊
이번 시간에는 동적 메모리 할당으로 확보한 메모리를 실제로 어떻게 사용해야 하는지
자세히 알아보는 시간을 가져볼게요!
📦 메모리를
malloc
이나calloc
으로 잘 “빌렸다면”,
이젠 그 공간을 안전하고 효율적으로 활용하는 법을 알아야겠죠?
그럼 지금부터 배열처럼 사용하는 방법부터 구조체, 문자열, 함수 리턴까지
동적 메모리를 실전 예제 중심으로 배워봅시다! 🚀
1. 동적 메모리는 “가변 크기”의 열쇠!
정적 메모리는 컴파일 시 고정되지만,
동적 메모리는 실행 중 필요한 만큼 할당되므로
입력에 따라 크기가 유동적인 구조를 만들 수 있어요.
예를 들어 사용자에게 배열 크기를 입력받고,
그 크기만큼 메모리를 할당해서 쓰는 게 가능하죠!
2. 기본 예제: 동적 배열 사용
c복사편집#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
printf("몇 개의 숫자를 입력할까요? ");
scanf("%d", &n);
int *arr = (int*) malloc(n * sizeof(int));
if (!arr) {
printf("메모리 할당 실패!
");
return 1;
}
// 값 입력 받기
for (int i = 0; i < n; i++) {
printf("%d번째 정수: ", i + 1);
scanf("%d", &arr[i]);
}
// 출력
printf("입력한 정수: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
free(arr);
return 0;
}
📌 사용자가 원하는 크기의 배열을 유연하게 처리할 수 있죠!
3. calloc()
으로 초기화된 배열 사용하기
c복사편집int *scores = (int*) calloc(10, sizeof(int));
-
이 코드는
int
10개의 공간을 0으로 초기화해서 할당합니다. -
배열처럼 접근 가능:
scores[0]
,scores[1]
…
✅ 반복문 없이도 초기값이 0인 배열이 필요한 경우,
calloc()
이 훨씬 깔끔해요!
4. 문자열 처리: char*
동적 할당
예제: 사용자 입력 문자열 받기
c복사편집#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char temp[100];
printf("이름을 입력하세요: ");
fgets(temp, sizeof(temp), stdin);
char *name = (char*) malloc(strlen(temp) + 1);
strcpy(name, temp);
printf("안녕하세요, %s", name);
free(name);
return 0;
}
💬 입력 받은 문자열의 길이만큼 정확히 메모리를 할당해 낭비 없이 저장할 수 있어요!
5. 구조체와 동적 메모리
c복사편집typedef struct {
char *name;
int age;
} Person;
int main() {
Person *p = (Person*) malloc(sizeof(Person));
p->name = (char*) malloc(50);
strcpy(p->name, "홍길동");
p->age = 30;
printf("이름: %s, 나이: %d
", p->name, p->age);
free(p->name);
free(p);
return 0;
}
📌 구조체 멤버 중 문자열처럼 동적 크기를 가진 항목은
별도로malloc()
으로 할당해줘야 해요!
6. 2차원 배열처럼 사용하기
c복사편집int **matrix = (int**) malloc(rows * sizeof(int*));
for (int i = 0; i < rows; i++) {
matrix[i] = (int*) malloc(cols * sizeof(int));
}
- 동적 2차원 배열처럼 사용 가능:
matrix[0][1]
,matrix[i][j]
해제
c복사편집for (int i = 0; i < rows; i++) {
free(matrix[i]);
}
free(matrix);
✅ 꼭 중첩된 할당 → 중첩된 해제를 기억하세요!
7. 함수에서 동적 메모리 사용하고 반환하기
c복사편집char* getGreeting() {
char *msg = (char*) malloc(20);
strcpy(msg, "Hello, World!");
return msg;
}
int main() {
char *text = getGreeting();
printf("%s
", text);
free(text);
return 0;
}
🎯 반환된 포인터를 받은 쪽에서 해제를 책임져야 해요!
8. 유의사항 및 메모리 안전 사용 팁
상황
설명
malloc
후 NULL 체크
할당 실패 시 예외 처리
free
후 NULL로 초기화
댕글링 포인터 방지
포인터 덮어쓰기 금지
기존 메모리 손실됨 (누수 발생)
구조체 해제
내부 포인터 멤버도 별도 free()
필요
반복문 할당
반복문 할당 시, 동일하게 반복 free()
도 필수
9. 흔한 실수와 방지법
❌ 실수 1: 포인터 덮어쓰기
c복사편집int *ptr = malloc(10);
ptr = malloc(20); // 첫 번째는 누수!
✅ 해결법:
c복사편집free(ptr);
ptr = malloc(20);
❌ 실수 2: free()
빼먹기
c복사편집void func() {
int *temp = malloc(100);
// free(temp); ← 없으면 누수!
}
✅ 해결법: 항상 free()
를 같이 작성하는 습관!
❌ 실수 3: 할당 크기 계산 실수
c복사편집int *arr = malloc(10); // ❌ 10바이트만 할당됨!
✅ 해결법:
c복사편집int *arr = malloc(10 * sizeof(int)); // ✅ 올바른 할당!
✅ 요약 정리
항목
설명
동적 배열
malloc
, calloc
→ 배열처럼 사용
문자열
strlen()
만큼 동적 할당 후 복사
구조체
내부 포인터도 별도 할당 필요
함수 반환
동적 메모리 반환 → 사용자가 free()
2차원 배열
행마다 별도로 malloc
, free
도 각 행별로
마무리하며 💬
동적 메모리는 C 언어에서 가장 강력하면서도 위험한 무기예요!
하지만 올바르게 사용하면 메모리를 낭비하지 않고,
사용자 맞춤형으로 유연한 프로그램을 만들 수 있죠.
🎯 “동적 메모리는 마치 칼과 같다.
잘 쓰면 요리사가 되지만, 잘못 쓰면 손을 다친다.”
다음 시간에는 이 동적 메모리를 좀 더 구조적으로 다룰 수 있는
메모리 풀 기법, 재사용 전략, 그리고 고급 예제들을 함께 공부해봐요!
오늘도 똑똑한 코드, 안전한 메모리! 💻🔥