728x90
반응형

shared_ptr 배열을 안전하게 관리하는 방법과 C++ 버전별 주의사항

소개

  • C++에서 동적 배열을 할당한 후 여러 객체에서 공유하며 자동으로 메모리를 해제하도록 관리하고 싶을 때 shared_ptr를 사용하는 것이 매우 유용합니다.
  • 하지만 배열 형태로 사용할 때는 버전에 따른 지원 차이와 주의할 점이 존재합니다.
  • 이러한 차이를 명확히 이해하지 못하면 메모리 누수나 잘못된 동작이 발생할 수 있습니다.
  • 따라서 각 C++ 표준에 따라 배열 관리 방식이 어떻게 달라지는지 이해하고 올바르게 사용하는 것이 중요합니다.


shared_ptr 할당 및 해제

  • shared_ptr는 기본적으로 단일 객체를 관리하는 용도로 설계되었지만, 배열 관리도 가능하도록 C++17 이후 일부 기능이 추가되었습니다.


1. C++11 / C++14

  • shared_ptr는 배열에 대한 자동 관리 기능을 지원하지 않습니다.

  • 배열을 할당하면 delete가 호출되므로 delete[]가 필요한 배열에는 잘못된 동작을 일으킬 수 있습니다.

  • 따라서 C++11/14에서는 배열을 shared_ptr로 관리할 경우 반드시 커스텀 deleter를 사용해야 합니다.

  • C++11/14

      std::shared_ptr<Employee> employees(new Employee[10], std::default_delete<Employee[]>());
    
  • std::default_delete : 기본 삭제 함수 객체(deleter)



2. C++17

  • C++17부터 shared_ptr<T[]>가 공식적으로 지원됩니다.

  • 이를 통해 배열 타입을 직접적으로 관리 할 수 있으며, delete[]가 자동으로 호출됩니다.

  • shared_ptr<Employee[]> 형식으로 선언이 가능하고, 배열 요소는 employees[i] 형태로 접근할 수 있습니다.

  • C++17

      std::shared_ptr<Employee[]> employees(new Employee[10]);
      employees[0] = Employee();
    


3. C++20 및 이후

  • make_shared<T[]>는 여전히 지원되지 않으므로 배열 초기화 시 make_shared를 사용할 수 없습니다.

  • 따라서 new 연산자와 함께 shared_ptr를 사용하는 방식 또는 커스텀 deleter 지정 방식이 여전히 권장됩니다.

  • C++20

      int main() {
          // 배열을 new로 생성하고 shared_ptr에 default_delete<T[]>로 전달
          std::shared_ptr<Employee> employees(new Employee[3], std::default_delete<Employee[]>());
      
          // 배열처럼 접근은 불가능하므로, 포인터를 얻어서 사용
          Employee* empArray = employees.get();
      
          for (int i = 0; i < 3; ++i) {
              empArray[i].work();
          }
      
          // shared_ptr 소멸 시 delete[] 호출
          return 0;
      }
    


정리

  • C++ 표준 배열 타입 지원 여부 추천 사용법
    C++11/14 지원하지 않음 shared_ptr<T> + default_delete<T[]> 커스텀 deleter 사용
    C++17 shared_ptr<T[]> 지원 std::shared_ptr<T[]> ptr(new T[size]); 방식 가능
    C++20 이후 make_shared<T[]> 미지원 new 할당 + shared_ptr 생성 또는 default_delete<T[]> 사용


배열 shared_ptr 요약

  • C++11/14에서는 배열 타입 사용 시, 반드시 커스텀 deleter를 지정해야 합니다.
  • C++17 이상에서는 배열 타입을 안전하게 지원하므로 shared_ptr<T[]> 형태로 사용할 수 있습니다.
  • C++20 이후에도 make_shared<T[]>는 지원되지 않으므로 new를 통한 생성 후 shared_ptr에 전달하는 방식이 필요합니다.

  • 버전 차이를 잘 이해하고 코드를 작성하면 배열 메모리 관리에서 발생할 수 있는 오류를 효과적으로 예방할 수 있습니다.



  • 도움이 되셨으면 하단의 ❤️ 공감 버튼 부탁 드립니다. 감사합니다! 😄

728x90
반응형

+ Recent posts