ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C++ 스마트 포인터 [unique_ptr , shared_ptr, weak_ptr]
    IT/C C++ 2023. 6. 15. 18:01
    반응형

    C++에서 스마트 포인터는 동적으로 할당된 메모리를 관리하는 데 사용되는 유용한 도구이다.  메모리 누수와 관련된 문제를 방지하고 자동으로 메모리를 해제함으로써 프로그램 안정성을 향상시키는 데 도움을 줄 수 있다.

    C++에는 다양한 스마트 포인터 종류가 있지만, 가장 일반적으로 사용되는 세 가지 스마트 포인터는 아래와 같다.

     

    1. unique_ptr: unique_ptr는 C++11에서 도입된 스마트 포인터로, 독점적 소유권을 가진다. 즉, 특정 객체에 대한 unique_ptr은 해당 객체를 독점적으로 소유하고 관리한다. 다른 unique_ptr이나 포인터에 할당하려고 시도하면 컴파일 오류가 발생하며, 이는 단일 소유자가 있고, 소유자가 객체의 수명을 관리하므로 메모리 누수를 방지하는 데 도움이 될 수 있다.
    #include <iostream>
    #include <memory>
    
    int main() {
        // int 타입의 동적으로 할당된 메모리를 관리하는 unique_ptr 선언
        std::unique_ptr<int> myPtr(new int(42));
    
        // unique_ptr을 사용하여 동적으로 할당된 메모리에 접근
        std::cout << "Value: " << *myPtr << std::endl;
    
        // unique_ptr은 독점적 소유권을 가지기 때문에 다른 포인터에 할당할 수 없음 (컴파일 오류)
        // std::unique_ptr<int> anotherPtr = myPtr;
    
        // unique_ptr은 소유권을 이전할 수는 있음
        std::unique_ptr<int> anotherPtr = std::move(myPtr);
    
        // 이제 anotherPtr이 동적으로 할당된 메모리를 소유함
        if (anotherPtr) {
            std::cout << "Value: " << *anotherPtr << std::endl;
        }
    
        // myPtr은 이제 null을 가리킴
        if (!myPtr) {
            std::cout << "myPtr is null" << std::endl;
        }
    
        // unique_ptr은 더 이상 사용하지 않을 때 자동으로 메모리를 해제함
        return 0;
    }

     

      2. shared_ptr: shared_ptr은 여러 개의 스마트 포인터가 같은 객체를 공유할 수 있도록 해준다. shared_ptr은 객체에 대한 공유 소유권을 가지며, 해당 객체를 참조하는 스마트 포인터의 수를 추적한다. 모든 shared_ptr이 객체를 더 이상 참조하지 않으면 객체는 자동으로 삭제된다. 이는 동적 메모리를 사용하는 동안 객체의 수명을 추적하는 데 도움이 되지만 순환 참조가 발생할 수 있으므로 주의가 필요하다.

    #include <iostream>
    #include <memory>
    
    int main() {
        // int 타입의 동적으로 할당된 메모리를 관리하는 shared_ptr 선언 및 생성
        std::shared_ptr<int> myPtr = std::make_shared<int>(42);
    
        // shared_ptr을 사용하여 동적으로 할당된 메모리에 접근
        std::cout << "Value: " << *myPtr << std::endl;
    
        // shared_ptr은 여러 개의 포인터가 같은 객체를 공유할 수 있음
        std::shared_ptr<int> anotherPtr = myPtr;
    
        // 두 개의 shared_ptr이 같은 객체를 공유하고 있음
        std::cout << "Value: " << *anotherPtr << std::endl;
    
        // shared_ptr은 객체를 더 이상 참조하지 않을 때 자동으로 메모리를 해제함
        return 0;
    }

    3. weak_ptr: weak_ptr은 shared_ptr과 함께 사용되며, 순환 참조를 방지하는 데 도움을 준다. weak_ptr은 객체를 소유하지 않지만 객체에 대한 약한 참조를 제공한다. weak_ptr은 객체가 존재하는지 확인하기 위해 shared_ptr로 변환될 수 있고, 객체가 삭제된 경우, weak_ptr은 자동으로 무효화 된다.

    #include <iostream>
    #include <memory>
    
    int main() {
        // int 타입의 동적으로 할당된 메모리를 관리하는 shared_ptr 선언 및 생성
        std::shared_ptr<int> sharedPtr = std::make_shared<int>(42);
    
        // shared_ptr을 사용하여 동적으로 할당된 메모리에 접근
        std::cout << "Value: " << *sharedPtr << std::endl;
    
        // shared_ptr로부터 weak_ptr 생성
        std::weak_ptr<int> weakPtr(sharedPtr);
    
        // weak_ptr을 사용하여 동적으로 할당된 메모리에 접근
        if (std::shared_ptr<int> sharedPtrFromWeak = weakPtr.lock()) {
            std::cout << "Value: " << *sharedPtrFromWeak << std::endl;
        } else {
            std::cout << "Memory has been released" << std::endl;
        }
    
        // shared_ptr을 해제하여 메모리를 해제함
        sharedPtr.reset();
    
        // weak_ptr은 더 이상 유효하지 않은 상태
        if (std::shared_ptr<int> sharedPtrFromWeak = weakPtr.lock()) {
            std::cout << "Value: " << *sharedPtrFromWeak << std::endl;
        } else {
            std::cout << "Memory has been released" << std::endl;
        }
    
        return 0;
    }


    스마트 포인터는 일반적으로 new 연산자를 사용하여 동적으로 할당된 객체를 관리하는 데 사용된다. 메모리 관리를 자동화하고 안전성을 높이기 때문에 수동으로 delete를 호출하여 메모리를 해제하는 것보다 훨씬 편리하고 안전하다. (new 해놓고 delete 안하는 실수를 막을 수 있음!) 스마트 포인터의 사용은 프로그램 안정성을 향상시키고 메모리 누수와 관련된 문제를 줄이는 데 도움이 되니 많이 사용하도록 하자.

     

     

    반응형

    'IT > C C++' 카테고리의 다른 글

    c++ iterator에서 vector 요소를 삭제하기 및 주의점  (1) 2023.06.17