본문 바로가기

C/C++

왜 delete는 포인터를 NULL로 만들지 않는가

 delete는 포인터를 NULL로 만들지 않는가

 

C++로 프로그래밍을 하다 보면보통 delete 연산 후에 해당 포인터를 NULL로 만들어 줘야 한다.

그렇다면, ‘언어차원에서, delete를 했을 때 NULL로 세팅해 줬으면 이런 귀찮은 작업을 피할 수 있는데왜 그렇게 하지 않았을까?

 

일단, c++ 창시자인 스트롭스트룹님이 한 이야기를 보자, [1]

 

delete p;

// ...

delete p;

… 부분에서 p에 관한 아무 작업도 하지 않았다면, C++은 심각한 에러를 낸다. C++은 이에 대해 효율적인 방어수단이 없기 때문이다.

pointer zero(0  or NULL)로 만드는 것이 나쁜 것은 아니지만위의 문제를 해결해 주지는 않는다.

 

delete 연산자가 lvalue(좌변)이 필요 하지 않은 이유가 있다.

일단 아래의 코드를 보면,

delete p+1;

delete f(x);

delete 구현은 위처럼 zero로 할당할 수 없는 포인터를 가질 수 있다이런 경우는 NULL로 세팅할 수 없다.

 

그리고 혹자는 이런 말을 한다.

성능 문제를 놓고 볼 때, delete를 한 이후에 바로 scope(범위)를 벗어나게 되면포인터를 NULL로 세팅하는 것이 시간만 소모할 뿐이다. C++은 그것이 필요 없는가그렇다면 그에 대한 대가도 지불할 필요가 없다” 라는 이데올로기를 갖고 있다.[2]

 

그리고 아래와 같은 말을 한다.

C++ explicitly allows an implementation of delete to zero out an lvalue operand, and I had hoped that implementations would do that, but that idea doesn't seem to have become popular with implementers.

다시 말해서, C++에서 delete 구현시 포인터를 명시적으로 zero로 만드는 것이 가능하고나 또한 그렇게 하고 싶다.

그러나 이 아이디어가 모든 사람들에게 인기가 있을 것 같진 않다.

 

그럼 어떻게 하느냐?

만약 pointer zero로 만들어 사용하고 싶으면아래와 같이 destroy와 같은 함수를 사용한다.

 

template<class Tinline void destroy(T*& p) { delete pp = 0; }

위와 같이 참조자로서 포인터를 넘겨주면, rlvaue(우변)를 파라미터로 넘겨서 삭제하지 못하게 해준다.

 

혹은 [3]에서 처럼 delete[]에 대해서도 구현 가능하다.

templateclass T > void SafeDelete( T*& pVal )
{
    
delete pVal;
    pVal = NULL;
}

templateclass T > void SafeDeleteArray( T*& pVal )
{
    
delete[] pVal;
    pVal = NULL;
}

 

 

사실이것보다 스마트 포인터(auto_ptr, scoped_ptr, shared_ptr)를 사용하는 것이 훨씬 좋다!!!

 

참조

1. http://www2.research.att.com/~bs/bs_faq2.html#delete-zero

2. http://stackoverflow.com/questions/704466/why-doesnt-delete-set-the-pointer-to-null

3. http://stackoverflow.com/questions/1265666/reason-why-not-to-have-a-delete-macro-for-c