ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C++] 댕글링 포인터 (Dangling Pointer)
    프로그래밍/C & C++ 2024. 7. 7. 22:05
    728x90
    반응형

    댕글링 포인터(Dangling Pointer)는 C++ 프로그래밍에서 매우 위험한 버그의 원인이 되는 문제로, 가리키는 대상이 더 이상 유효하지 않은 포인터를 말합니다. 이는 주로 동적 메모리를 관리할 때 발생할 수 있으며, 메모리 누수나 예기치 않은 동작을 일으킬 수 있습니다.

    댕글링 포인터가 발생하는 상황

    1. 해제된 메모리를 참조할 때
      delete 또는 delete[]를 사용하여 메모리를 해제한 후, 여전히 그 메모리를 가리키는 포인터가 남아있는 경우.

       int* p = new int(5);
       delete p;
       // p는 이제 댕글링 포인터가 됨
       *p = 10;  // 정의되지 않은 동작 (Undefined Behavior)
    2. 스택 메모리 참조
      함수가 종료된 후에도 지역 변수를 가리키는 포인터가 남아있는 경우.

       int* danglingPointer() {
           int localVar = 10;
           return &localVar;  // localVar은 함수가 끝나면 소멸됨
       }
      
       int main() {
           int* p = danglingPointer();
           // p는 이제 댕글링 포인터가 됨
           *p = 5;  // 정의되지 않은 동작
           return 0;
       }
    3. 객체가 소멸된 후 참조
      객체가 소멸된 후, 그 객체의 멤버에 대한 포인터가 남아있는 경우.

       class MyClass {
       public:
           int value;
       };
      
       int main() {
           MyClass* obj = new MyClass();
           int* p = &obj->value;
           delete obj;
           // obj와 그 멤버 value는 더 이상 유효하지 않음
           *p = 10;  // 정의되지 않은 동작
           return 0;
       }

    댕글링 포인터를 방지하는 방법

    1. 포인터를 nullptr로 초기화 및 설정
      메모리를 해제한 후 포인터를 nullptr로 설정하여, 해제된 메모리를 다시 참조하는 것을 방지합니다.

       int* p = new int(5);
       delete p;
       p = nullptr;  // p를 nullptr로 설정하여 더 이상 사용하지 않도록 함
    2. 스마트 포인터 사용
      C++11 이후, 스마트 포인터(std::unique_ptr, std::shared_ptr)를 사용하여 자동으로 메모리를 관리합니다.

       #include <memory>
      
       int main() {
           std::unique_ptr<int> p = std::make_unique<int>(5);
           // 메모리는 자동으로 관리되고, 댕글링 포인터가 발생하지 않음
           return 0;
       }
    3. 객체의 수명 관리
      객체의 수명을 명확히 관리하여, 소멸된 객체를 참조하지 않도록 합니다. 예를 들어, 객체의 소멸 후 그 객체를 참조하는 포인터를 사용하지 않도록 주의합니다.

    4. RAII (Resource Acquisition Is Initialization) 원칙
      객체의 생명 주기를 관리하여 자원을 할당하고 해제하는 것을 객체의 생성자와 소멸자에서 처리합니다.

       #include <iostream>
      
       class Resource {
       public:
           Resource() { std::cout << "Resource acquired\n"; }
           ~Resource() { std::cout << "Resource released\n"; }
       };
      
       void useResource() {
           Resource res;
           // res는 함수가 끝날 때 자동으로 소멸됨
       }
      
       int main() {
           useResource();
           // Resource는 자동으로 해제됨
           return 0;
       }

    결론

    댕글링 포인터는 매우 위험한 버그를 초래할 수 있으므로, 이를 방지하기 위해서는 메모리 관리를 철저히 해야 합니다. 스마트 포인터를 사용하고, 포인터를 해제한 후 nullptr로 설정하며, RAII 원칙을 따르는 등의 방법으로 댕글링 포인터를 예방할 수 있습니다. 이러한 방식을 통해 더 안전하고 안정적인 코드를 작성할 수 있습니다.

    728x90
    반응형

    '프로그래밍 > C & C++' 카테고리의 다른 글

    [C++] Explicit  (0) 2024.07.08
    [C++] 대입연산자  (0) 2024.07.08
    [C++] 클래스 생성자 맴버 초기화  (0) 2024.07.07
    [C++] Delete  (0) 2024.07.07
    [C++] Mutable  (0) 2024.07.07
Designed by Tistory.