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
포인터와 함수 (Pointer & Function)
4 / 24
메모리 레이아웃 (Memory Layout)
☆ Star
↗ Full
스택과 힙 (Stack & Heap)
#c
#c-lang
#intermediate
#memory
#stack
@devpc
|
2026-03-29 13:06:56
|
GET /api/v1/flows/5/nodes/44?fv=2&nv=2
Context:
Flow v2
→
Node v2
0
Views
5
Calls
# 스택과 힙 (Stack & Heap) ## 메모리의 두 가지 영역 C 프로그램에서 런타임에 사용하는 메모리는 크게 **스택(Stack)** 과 **힙(Heap)** 으로 나뉩니다. ``` 높은 주소 ┌──────────────┐ │ Stack │ ← 함수 호출, 지역 변수 (자동 관리) │ ↓ │ │ │ │ ↑ │ │ Heap │ ← malloc/free (수동 관리) ├──────────────┤ │ BSS │ 초기화되지 않은 전역/정적 변수 ├──────────────┤ │ Data │ 초기화된 전역/정적 변수 ├──────────────┤ │ Text │ 실행 코드 (read-only) └──────────────┘ 낮은 주소 ``` --- ## 스택 (Stack) ### 특징 - 함수가 호출될 때 **자동으로 할당**, 반환될 때 **자동으로 해제** - LIFO (Last In, First Out) 구조 - 크기가 고정되어 있음 (보통 1~8 MB) - 매우 빠름 ### 예시 ```c void foo(void) { int x = 10; // 스택에 할당 int y = 20; // 스택에 할당 printf("%d\n", x + y); } // foo() 종료 시 x, y 자동 해제 ``` ``` foo() 호출 시 스택 프레임: ┌──────────┐ │ y = 20 │ │ x = 10 │ │ 반환주소 │ └──────────┘ ``` ### 스택 오버플로우 재귀 호출이 너무 깊거나 너무 큰 지역 변수 선언 시 발생합니다. ```c void infinite(void) { int arr[100000]; // 매 호출마다 스택 소모 infinite(); // 무한 재귀 → Stack Overflow } ``` --- ## 힙 (Heap) ### 특징 - `malloc`, `calloc`, `realloc`으로 **수동 할당** - `free`로 **수동 해제** 필요 - 크기가 유연함 (가용 메모리 한도) - 스택보다 느리지만 대용량 할당 가능 ### 예시 ```c #include <stdlib.h> void foo(void) { int *p = malloc(sizeof(int) * 5); // 힙에 20바이트 할당 if (p == NULL) { perror("malloc"); return; } for (int i = 0; i < 5; i++) { p[i] = i * 10; } free(p); // 반드시 수동 해제 p = NULL; } ``` --- ## 스택 vs 힙 비교 | 구분 | 스택 (Stack) | 힙 (Heap) | |------|-------------|-----------| | 할당 방식 | 자동 | 수동 (`malloc`) | | 해제 방식 | 자동 (함수 종료 시) | 수동 (`free`) | | 속도 | 빠름 | 상대적으로 느림 | | 크기 | 제한적 (~8MB) | 대용량 가능 | | 생명주기 | 함수 범위 | 개발자가 제어 | | 주요 위험 | 스택 오버플로우 | 메모리 누수, 이중 해제 | --- ## 생명주기 비교 ```c int *stack_danger(void) { int local = 42; return &local; // ⚠️ 위험! 함수 종료 후 스택 변수 주소 반환 } // 해제된 메모리를 가리키는 댕글링 포인터 int *heap_safe(void) { int *p = malloc(sizeof(int)); *p = 42; return p; // ✅ 힙은 함수 종료 후에도 유효 } // 단, 호출한 쪽에서 반드시 free() 해야 함 ``` --- ## 정리 | 키워드 | 설명 | |--------|------| | Stack | 자동, 빠름, 함수 범위 생명주기 | | Heap | 수동, 유연, 개발자가 해제 책임 | | 스택 오버플로우 | 너무 깊은 재귀 또는 큰 지역 변수 | | 댕글링 포인터 | 해제된 스택 변수의 주소 반환 | ---
포인터와 함수 (Pointer & Function)
메모리 레이아웃 (Memory Layout)
// COMMENTS
ON THIS PAGE
No content selected.