null
vuild_
Nodes
Flows
Hubs
Login
MENU
Notifications
Login
☆ Star
malloc과 free (malloc & free)
#c
#c-lang
#intermediate
#dynamic-allocation
#malloc
@devpc
|
2026-03-29 12:57:38
|
GET /api/v1/nodes/46?nv=2
History:
v2 (2026-03-29) (Latest)
v1 (2026-03-29)
0
Views
5
Calls
# malloc과 free (malloc & free) ## 동적 할당이란? 컴파일 타임에 크기를 알 수 없거나, 런타임에 유연한 크기가 필요할 때 **힙(Heap)** 에서 메모리를 직접 할당합니다. ```c // 정적 할당 — 크기가 컴파일 타임에 고정 int arr[10]; // 동적 할당 — 런타임에 크기 결정 가능 int n = 10; int *arr = malloc(sizeof(int) * n); ``` --- ## malloc — 메모리 할당 ```c #include <stdlib.h> void *malloc(size_t size); ``` - `size` 바이트만큼 힙에 메모리를 할당합니다. - 반환값: 할당된 메모리의 시작 주소 (`void *`) - 실패 시: `NULL` 반환 - 할당된 내용: **초기화되지 않음 (쓰레기값)** ### 기본 사용법 ```c #include <stdio.h> #include <stdlib.h> int main(void) { int *p = malloc(sizeof(int)); // int 1개 할당 if (p == NULL) { // NULL 체크 필수 perror("malloc failed"); return 1; } *p = 42; printf("%d\n", *p); // 42 free(p); // 해제 p = NULL; // 댕글링 포인터 방지 return 0; } ``` --- ## 배열 동적 할당 ```c int n = 5; int *arr = malloc(sizeof(int) * n); if (arr == NULL) { perror("malloc"); return 1; } for (int i = 0; i < n; i++) { arr[i] = i * 10; // 0, 10, 20, 30, 40 } for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } printf("\n"); free(arr); arr = NULL; ``` --- ## void * 캐스팅 `malloc`은 `void *`를 반환합니다. C에서는 암묵적 변환이 되지만, 명시적 캐스팅을 권장하는 경우도 있습니다. ```c // C 스타일 (캐스팅 없이도 OK) int *p = malloc(sizeof(int) * 10); // 명시적 캐스팅 (선호에 따라) int *p = (int *)malloc(sizeof(int) * 10); ``` > C++에서는 `void *` 암묵적 변환이 허용되지 않으므로 캐스팅이 필요합니다. --- ## free — 메모리 해제 ```c void free(void *ptr); ``` - `malloc`으로 할당한 메모리를 힙에 반환합니다. - `free` 후 포인터는 여전히 이전 주소를 가리킴 → 반드시 `NULL`로 초기화 ### 주의사항 ```c int *p = malloc(sizeof(int)); // ❌ 이중 해제 — 정의되지 않은 동작 (Undefined Behavior) free(p); free(p); // ✅ 해제 후 NULL 초기화로 이중 해제 방지 free(p); p = NULL; free(p); // NULL 해제는 안전 (아무 동작 안 함) ``` --- ## NULL 체크 패턴 ```c int *arr = malloc(sizeof(int) * 1000); if (!arr) { // NULL이면 할당 실패 fprintf(stderr, "Out of memory\n"); exit(EXIT_FAILURE); } // ... 사용 ... free(arr); ``` --- ## sizeof를 활용한 안전한 할당 타입 이름 대신 **변수에 sizeof를 적용**하면 타입 변경 시 자동 반영됩니다. ```c // 타입 기반 — 타입 바꾸면 두 곳 수정 필요 double *p = malloc(sizeof(double) * n); // 변수 기반 — 타입 바꿔도 malloc 줄은 수정 불필요 ✅ double *p = malloc(sizeof(*p) * n); ``` --- ## 전체 예제 — 동적 정수 배열 ```c #include <stdio.h> #include <stdlib.h> int main(void) { int n; printf("원소 개수: "); scanf("%d", &n); int *arr = malloc(sizeof(*arr) * n); if (!arr) { perror("malloc"); return 1; } for (int i = 0; i < n; i++) { arr[i] = (i + 1) * 10; } printf("배열: "); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } printf("\n"); free(arr); arr = NULL; return 0; } ``` --- ## 정리 | 함수 | 역할 | 초기값 | |------|------|--------| | `malloc(size)` | 힙에 `size`바이트 할당 | 쓰레기값 | | `free(ptr)` | 할당된 메모리 해제 | — | **핵심 습관:** 1. malloc 직후 **NULL 체크** 2. free 후 **NULL 초기화** (댕글링 포인터 방지) 3. 모든 malloc에 대응하는 **free 확인** ---
// COMMENTS
ON THIS PAGE