본문 바로가기
언어/C, C++

메모리 누수

by minhyeok.lee 2025. 6. 2.
반응형

✅ 메모리 누수

할당한 메모리(힙 메모리)를 해제하지 않아서 다시 사용할 수 없는 상태로 남아 있는 것


💥 결과

  • 프로그램 종료 전까지 RAM 점유
  • 반복되면 메모리 부족, 시스템 느려짐, 크래시 발생

✅ 어떤 경우에 발생하나?

1. delete를 호출하지 않은 경우

void createLeak() {
    int* ptr = new int(10);
    // delete ptr; ❌ 안 했음
}
  • ptr은 지역 변수로 함수 종료 시 사라지지만, new로 할당된 메모리는 남음

2. 포인터가 덮어써질 때

int* ptr = new int(5);
ptr = new int(10); // 이전에 할당한 5는 참조할 방법이 없어짐 ❌ 메모리 누수

3. 예외가 발생했는데 해제를 못했을 때

void risky() {
    int* ptr = new int[100];
    throw std::runtime_error("Oops!"); // delete[] ptr; 실행되지 않음 ❌
}

4. 소멸자가 호출되지 않은 경우

가장 실무적으로 많이 발생하는 상황 → 가상 소멸자 미사용

class Base {
public:
    virtual void run() = 0;
    ~Base() { std::cout << "Base destroyed\n"; } // ❌ 가상 아님
};

class Derived : public Base {
public:
    ~Derived() { std::cout << "Derived destroyed\n"; } // 해제 안 됨
};

void func() {
    Base* b = new Derived();
    delete b; // Base의 소멸자만 호출됨 → Derived 리소스 누수
}

✅ 디버깅하기 어려운 이유

  • 프로그램은 정상적으로 실행됨
  • 누수가 누적될수록 이상 현상이 발생 (속도 저하, 크래시)
  • 누수 위치 추적이 어려움

✅ 해결책

방법 설명
deletedelete[] 정확히 사용 new → delete / new[] → delete[]
unique_ptr, shared_ptr 사용 RAII 패턴 기반 자동 메모리 관리
가상 소멸자 사용 다형성 객체 해제 시 자식 소멸자까지 호출
예외 안전 코드 try/catch 또는 스마트 포인터 사용
valgrind, ASAN 등 도구 사용 리눅스/맥에서는 누수 탐지 도구로 확인 가능

✅ 스마트 포인터로 누수 방지 예시

#include <memory>

void safe() {
    std::unique_ptr<int> ptr(new int(10)); // 자동 해제
    // 또는 auto ptr = std::make_unique<int>(10);
}

✅ 요약

항목 요약
발생 원인 delete 누락, 포인터 덮어쓰기, 예외 등
실전 위험 반복되면 성능 저하, 크래시
가상 소멸자 다형성 기반 해제에서 반드시 필요
방지 방법 스마트 포인터, RAII, 도구 사용
반응형

'언어 > C, C++' 카테고리의 다른 글

Interface vs concept  (1) 2025.06.04
[c++] concept  (0) 2025.06.03
[C++] 인터페이스(Interface) 정리  (0) 2025.05.31
DI(Dependency Injection), DIP(Dependency Inversion Principle)  (0) 2025.05.22
c, c++ 임베디드 설계 비교  (1) 2025.05.21

댓글