C언어 초급 - 11장: 동적 메모리 할당 (11.2 메모리 누수 방지와 free() 함수의 중요성)

2025. 2. 24. 11:52프로그래밍 언어/C

11.2 메모리 누수 방지와 free() 함수의 중요성

1. 메모리 누수란?

메모리 누수(Memory Leak)프로그램에서 동적으로 할당한 메모리를 해제하지 않아, 사용되지 않는 메모리가 계속 남아있는 현상입니다.
C 언어는 자동 메모리 관리 기능이 없기 때문에, 동적 할당(malloc(), calloc(), realloc())으로 확보한 메모리는 반드시 free()를 사용하여 직접 해제해야 합니다.

📌 메모리 누수가 발생하면?

  • 점점 사용 가능한 메모리가 줄어들어 프로그램이 느려지고 결국 충돌(Crash) 발생.
  • 특히, 장시간 실행되는 프로그램(서버, 임베디드 시스템 등)에서 심각한 문제 유발.

해결 방법: 동적 메모리 할당 후 반드시 free()를 호출하여 메모리를 해제해야 함.


2. free() 함수란?

2.1 free()의 역할

  • malloc(), calloc(), realloc()으로 할당된 메모리를 해제.
  • 해제된 메모리는 다시 사용할 수 있도록 시스템에 반환됨.
  • 해제되지 않은 메모리는 프로그램이 종료될 때까지 계속 점유됨메모리 누수 발생.

2.2 free() 사용법

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *ptr = (int *)malloc(5 * sizeof(int));  // 동적 메모리 할당

    if (ptr == NULL) {
        printf("메모리 할당 실패\n");
        return 1;
    }

    printf("메모리 할당 후 ptr: %p\n", ptr);

    free(ptr);  // 할당된 메모리 해제
    printf("메모리 해제 완료\n");

    return 0;
}

출력 예시

메모리 할당 후 ptr: 0x7ffee3b3d9c0
메모리 해제 완료

📌 설명

  • free(ptr); → ptr이 가리키던 메모리를 해제하여 시스템에 반환.
  • 할당된 메모리는 반드시 free()를 사용하여 해제해야 함.

3. 메모리 누수 발생 예제

3.1 메모리를 해제하지 않은 경우

#include <stdio.h>
#include <stdlib.h>

void memoryLeak() {
    int *ptr = (int *)malloc(10 * sizeof(int));  // 동적 메모리 할당
    if (ptr == NULL) {
        printf("메모리 할당 실패\n");
        return;
    }
    // 메모리를 해제하지 않고 함수 종료 → 메모리 누수 발생!
}

int main() {
    memoryLeak();  // 메모리 누수가 발생하는 함수 호출
    return 0;
}

문제점

  • malloc()을 사용하여 메모리를 할당했지만, free()로 해제하지 않음.
  • 함수가 종료되면서 ptr 변수가 사라지지만, 할당된 메모리는 여전히 점유됨.
  • 이 코드가 여러 번 실행되면 메모리가 계속 증가하여 시스템에 부담이 됨.

해결 방법: malloc() 후에는 반드시 free()를 호출해야 함.


4. 메모리 누수를 방지하는 방법

4.1 free()를 사용하여 메모리 해제

#include <stdio.h>
#include <stdlib.h>

void preventMemoryLeak() {
    int *ptr = (int *)malloc(10 * sizeof(int));  // 동적 메모리 할당
    if (ptr == NULL) {
        printf("메모리 할당 실패\n");
        return;
    }

    printf("메모리 할당 성공\n");

    free(ptr);  // 메모리 해제
    printf("메모리 해제 완료\n");
}

int main() {
    preventMemoryLeak();
    return 0;
}

출력 결과

메모리 할당 성공
메모리 해제 완료

📌 설명

  • malloc()으로 할당한 메모리를 사용한 후, free(ptr);을 호출하여 해제.
  • 메모리 누수 없이 안전하게 사용 가능.

4.2 NULL 할당하여 Dangling Pointer 방지

메모리를 해제한 후, 포인터 변수를 NULL로 설정하면 해제된 메모리를 다시 참조하는 실수를 방지할 수 있음.

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *ptr = (int *)malloc(5 * sizeof(int));

    if (ptr == NULL) {
        printf("메모리 할당 실패\n");
        return 1;
    }

    free(ptr);  // 메모리 해제
    ptr = NULL; // 포인터를 NULL로 설정 (Dangling Pointer 방지)

    return 0;
}

Dangling Pointer란?

  • 해제된 메모리를 계속 가리키는 포인터.
  • 이 포인터를 사용하면 예상치 못한 동작이 발생할 수 있음.

📌 해결 방법: free(ptr); 호출 후 ptr = NULL;로 초기화.


4.3 메모리 할당과 해제의 균형 유지

다음과 같은 원칙을 따르면 메모리 누수를 방지할 수 있음.

원칙  설명
malloc() 후 반드시 free() 호출 메모리를 할당한 후 반드시 해제
free() 후 포인터를 NULL로 초기화 해제된 메모리를 다시 참조하는 실수 방지
realloc() 후 기존 포인터 해제 필요 realloc()이 새로운 주소를 반환하면 기존 주소를 해제해야 함
반복문 내에서 동적 할당 시 해제 필요 반복문에서 여러 번 할당되면 메모리가 증가할 수 있음

5. 정리

개념  설명  예제
메모리 누수 malloc(), calloc(), realloc() 후 free()를 호출하지 않으면 발생 int *p = (int *)malloc(10 * sizeof(int));
free() 함수 동적 메모리를 해제하여 메모리 누수를 방지 free(p);
Dangling Pointer 방지 free() 후 포인터를 NULL로 초기화 p = NULL;
반복문 내 메모리 해제 반복문에서 메모리 할당 시 free()를 호출해야 함 for (i=0; i<n; i++) { p = malloc(); free(p); }

📌 동적 할당된 메모리는 반드시 free()로 해제해야 함
📌 Dangling Pointer를 방지하려면 free() 후 NULL을 할당
📌 반복문에서 malloc()을 여러 번 호출하면 free()도 함께 호출해야 함