ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Effective C++...49
    일지 2022. 8. 28. 13:00

    new 및 delete를 작성할 때 따라야 할 기존의 관례를 잘 알아 두자

    operator new의 관례

    new는 몇 가지 관례가 존재하는데 먼저 0바이트가 요구되었을 때도 적법한 포인터를 반환해야 한다는 것이다.

    이에 대해서는 0바이트가 요구될 때는 1바이트로 가정해서 작업을 진행한다.


    void* operator new(std::size_t size) throw(std::bad_alloc)

    {

        using namespace std;

        if (size == 0) {

            size = 1;

        }

        while(true) {

            if (할당 성공)

                return 할당된 메모리의 포인터;

     

            // 할당 실패 시 new 처리자 함수가 있으면 그것을 실행, 아니면 bad_alloc 예외를 발생시킨다.

        }

    }


     

    또, operator new에는 무한 루프가 들어가서 두 번 이상 할당을 시도하게 되는데 위의 함수에서 while(true) 부분에서 확인할 수 있다.

     

    ※ 무한 루프에 갇히지 않기 위해서는 new 처리자 함수 쪽에서는 네 가지 동작 중 하나를 반드시 해 줘야 한다.

     

    operator new가 파생되었을 때 Base클래스와 Derived클래스의 크기가 다르다면 operator new가 정상적으로 동작하지 않을 수 있다. 따라서 크기를 검사해서 크기가 다르면 기존의 operator new를 호출해줘야 한다.


    void* Base::operator new(std::size_t size) throw(std::bad_alloc)

    {

        if (size != sizeof(Base))

            return ::operator new(size);

        ...

    }


     

    operator delete의 관례

    C++에서는 널 포인터에 대한 delete 적용이 항상 안전해야 한다는 것 외에는 크게 관례가 존재하지 않는다.


    void operator delete(void* rawMemory) throw()

    {

        if (rawMemory == 0) return;

        ...

    }


     

    가상 소멸자가 없는 기본 클래스에서 파생된 클래스를 제거할 때 operator delete로 전달되는 size가 엉망일 수 있다. 따라서 클래스를 파생시킬 때는 반드시 가상 소멸자를 사용해야 한다.

     

    댓글

Designed by Tistory.