null
vuild_
Nodes
Flows
Hubs
Login
MENU
Notifications
Login
⌂
c-lang-intermediate
Structure
pointers
•
포인터 기초 (Pointer Basics)
•
배열과 포인터 (Pointer & Array)
•
포인터와 함수 (Pointer & Function)
memory
•
스택과 힙 (Stack & Heap)
•
메모리 레이아웃 (Memory Layout)
dynamic-alloc
•
malloc과 free (malloc & free)
•
calloc과 realloc
•
메모리 누수 (Memory Leak)
struct
•
구조체 기초 (Struct Basics)
•
중첩 구조체, 구조체 배열, 구조체 포인터
•
union과 enum
file-io
•
파일 열기와 닫기 (fopen / fclose)
•
파일 읽기와 쓰기 (Read & Write)
•
바이너리 파일 (Binary File)
preprocessor
•
#define과 매크로 (Define & Macro)
•
헤더 중복 포함 방지 (Include Guard)
•
조건부 컴파일 (Conditional Compilation)
multi-file
•
헤더 파일 (Header Files)
•
extern과 static (Extern & Static)
•
Makefile 기초 (Makefile Basics)
debugging
•
GDB 기초 (GDB Basics)
•
Valgrind
•
자주 발생하는 C 오류 (Common Errors)
project
•
종합 프로젝트: 학생 관리 시스템 (Student Manager)
Flow Structure
malloc과 free (malloc & free)
7 / 24
메모리 누수 (Memory Leak)
☆ Star
↗ Full
calloc과 realloc
#c
#c-lang
#intermediate
#dynamic-allocation
#calloc
@devpc
|
2026-03-29 13:06:58
|
GET /api/v1/flows/5/nodes/47?fv=2&nv=2
Context:
Flow v2
→
Node v2
0
Views
6
Calls
# calloc과 realloc ## calloc — 초기화된 동적 할당 ```c #include <stdlib.h> void *calloc(size_t nmemb, size_t size); ``` - `nmemb`개의 원소를 `size` 바이트씩, 총 `nmemb * size` 바이트 할당 - **모든 바이트를 0으로 초기화** - 실패 시 `NULL` 반환 ### malloc vs calloc ```c // malloc — 쓰레기값 int *a = malloc(sizeof(int) * 5); // a: {쓰레기, 쓰레기, 쓰레기, 쓰레기, 쓰레기} // calloc — 0으로 초기화 int *b = calloc(5, sizeof(int)); // b: {0, 0, 0, 0, 0} ``` ### calloc 사용 예시 ```c #include <stdio.h> #include <stdlib.h> int main(void) { int n = 5; int *arr = calloc(n, sizeof(int)); if (!arr) { perror("calloc"); return 1; } // 초기화 없이 바로 사용 가능 for (int i = 0; i < n; i++) { printf("%d ", arr[i]); // 0 0 0 0 0 } printf("\n"); free(arr); return 0; } ``` ### calloc을 쓸 때 | 상황 | 선택 | |------|------| | 즉시 모든 원소에 값을 쓸 경우 | `malloc` (초기화 불필요) | | 일부만 쓰고 나머지는 0이어야 할 경우 | `calloc` | | 구조체 배열의 안전한 초기화 | `calloc` | > ⚠️ `calloc`은 내부적으로 `memset(ptr, 0, ...)`을 수행하므로 `malloc`보다 약간 느릴 수 있습니다. --- ## realloc — 크기 변경 ```c void *realloc(void *ptr, size_t new_size); ``` - 이미 할당된 메모리 블록의 크기를 `new_size`로 변경 - 가능하면 **기존 위치 확장**, 불가능하면 **새 위치로 이동 후 복사** - 원본 데이터는 보존 (새 크기가 더 클 경우 추가 공간은 초기화 안 됨) - 실패 시 `NULL` 반환 (원본 포인터는 여전히 유효) ### realloc 사용 예시 ```c #include <stdio.h> #include <stdlib.h> int main(void) { int *arr = malloc(sizeof(int) * 3); if (!arr) return 1; arr[0] = 10; arr[1] = 20; arr[2] = 30; // 크기를 3 → 6으로 확장 int *tmp = realloc(arr, sizeof(int) * 6); if (!tmp) { free(arr); // 실패 시 원본 해제 return 1; } arr = tmp; // 성공 시 포인터 교체 arr[3] = 40; arr[4] = 50; arr[5] = 60; for (int i = 0; i < 6; i++) { printf("%d ", arr[i]); // 10 20 30 40 50 60 } printf("\n"); free(arr); return 0; } ``` ### ❌ 흔한 실수 — realloc 결과를 원본에 바로 대입 ```c // 위험한 패턴 arr = realloc(arr, new_size); // realloc이 NULL을 반환하면 arr도 NULL이 되어 원본 주소를 잃음 → 메모리 누수 ``` ```c // 안전한 패턴 int *tmp = realloc(arr, new_size); if (tmp == NULL) { free(arr); // 원본 해제 return 1; } arr = tmp; // 안전하게 교체 ``` --- ## 동적 배열 성장 패턴 실제 프로젝트에서 사용하는 동적 배열 구현 예시입니다. ```c #include <stdio.h> #include <stdlib.h> int main(void) { int capacity = 4; int size = 0; int *arr = malloc(sizeof(int) * capacity); if (!arr) return 1; // 10개의 값을 동적으로 추가 for (int i = 0; i < 10; i++) { if (size == capacity) { capacity *= 2; // 용량을 두 배로 int *tmp = realloc(arr, sizeof(int) * capacity); if (!tmp) { free(arr); return 1; } arr = tmp; printf("realloc → capacity: %d\n", capacity); } arr[size++] = i * 10; } for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } printf("\n"); free(arr); return 0; } ``` --- ## 세 함수 비교 요약 | 함수 | 초기화 | 용도 | |------|--------|------| | `malloc(size)` | ❌ (쓰레기값) | 일반적인 동적 할당 | | `calloc(n, size)` | ✅ (0으로) | 0 초기화가 필요한 경우 | | `realloc(ptr, size)` | ❌ (기존값 유지) | 크기 변경 | ---
malloc과 free (malloc & free)
메모리 누수 (Memory Leak)
// COMMENTS
ON THIS PAGE
No content selected.