[C언어] 힙 메모리 할당(malloc/free) 동작 원리와 free 후 주소가 남아 발생하는 댕글링 포인터(Use-After-Free) 방어법

자신감·2026년 9월 21일

5주차

목록 보기
4/11

1. 메모리(RAM)와 힙(Heap) 영역의 물리적 정의

컴퓨터의 RAM은 1바이트마다 0, 1, 2, 3처럼 1씩 증가하는 일련번호(메모리 주소)가 붙어 있는 물리적 반도체 공간입니다.

  • 스택 (Stack): 함수 안에서 선언된 일반 지역 변수가 사용하는 메모리입니다. 함수가 끝나면 CPU가 스택 포인터 레지스터를 이동시켜 자동으로 지워버립니다.
  • 힙 (Heap): 프로그램 실행 중에 크기가 유동적으로 변하거나, 함수가 끝나도 메모리를 계속 보존해야 할 때 운영체제에 요청하여 할당받는 메모리 영역입니다. 사용자가 직접 해제하기 전까지 메모리에 유지됩니다.

2. malloc()과 free()의 실제 실행 동작

int *ptr = (int *)malloc(sizeof(int)); // 1단계: 힙 메모리 4바이트 할당
*ptr = 42;                             // 2단계: 주소에 숫자 42 저장
free(ptr);                             // 3단계: 힙 메모리 사용 권한 반납
  1. malloc(4): 운영체제가 힙 영역에서 비어 있는 연속된 4바이트 공간(예: 주소 0x5000번지)의 사용 권한을 부여하고, 그 시작 주소 번호인 숫자 0x5000을 반환합니다.
  2. *ptr = 42: 포인터 변수 ptr에 저장된 주소 0x5000번지로 이동하여 4바이트 공간에 숫자 42를 2진수로 기록합니다.
  3. free(ptr): 운영체제에 "주소 0x5000번지의 4바이트 공간을 이제 다른 변수나 코드가 써도 된다"고 알립니다.

3. 댕글링 포인터(Dangling Pointer)가 발생하는 기계적 원인

  • free(ptr);을 실행하면 0x5000번지의 힙 메모리 사용 권한만 반납됩니다.
  • 포인터 변수 ptr 안에 들어있던 숫자 0x5000은 컴퓨터가 0으로 자동으로 지워주지 않으므로 그대로 남아 있습니다.
  • 이미 반납되어 쓸 권한이 없는 주소 번호를 여전히 갖고 있는 포인터를 댕글링 포인터라고 부릅니다.

4. Use-After-Free(해제 후 재사용) 버그의 위험성

free(ptr);   // 0x5000 주소를 반납함
*ptr = 100;  // 반납된 0x5000 주소에 숫자 100을 덮어씀 (심각한 오류)
  • 반납된 주소 0x5000은 나중에 호출된 다른 malloc에 의해 전혀 다른 데이터나 함수 주소가 배치될 수 있습니다.
  • 이때 댕글링 포인터 ptr을 통해 숫자를 덮어쓰면, 새로 할당된 다른 변수의 데이터가 깨지거나 프로그램이 비정상 종료(Segmentation Fault)됩니다.

5. 해결 방법: free 직후 NULL 대입

free(ptr);
ptr = NULL; // ptr 내부의 숫자를 0x0(접근 불가 주소)으로 변경
  • 포인터 변수를 NULL(주소 0)로 바꿔두면, 이후 실수로 *ptr을 실행하더라도 운영체제가 즉시 에러를 발생시키며 프로그램을 안전하게 멈추어 주므로 다른 메모리가 오염되는 것을 차단합니다.
profile
잘할 수밖에 없는 자신감

0개의 댓글