C++ 이야기 세번째: new 와 delete

Posted at 2007.03.09 06:01 // in S/W개발/C++ 이야기 // by 김윤수


[이글의 최신 Update 문서는 항상 여기에서 확인할 수 있습니다]

C++ 이야기 세번째입니다. 개발자가 아니신 분들이나 C++ 로 주로 개발하지 않으시는 분들은 별로 관심이 가는 내용이 아닐 것 같네요.

크~ 벌써 세번째에 접어 들었네요. 이번에는 new 와 delete에 대해서 알아보도록 하겠습니다. new 와 delete에 대해서는 다 잘 아는 건데 이것보다 딴 걸 알고 싶으신 분은 잠깐 기다려 보세요. 이 글을 다 읽으신 후에는 new 와 delete의 오묘한 세계에 다시 한 번 놀라실 겁니다. 저도 놀랐다니까요~ 글쎄

먼저 여러분이 가장 기본적으로 알고 있는 것부터 확인하고 넘어갈까요 ?

* new: 객체 하나를 동적으로 할당해 줍니다.
* delete: 동적으로 할당된 객체 하나를 삭제합니다.
* new []: 객체의 배열을 동적으로 할당해 줍니다.
* delete []: 동적으로 할당된 객체의 배열을 삭제합니다.

다 잘 알고 있는 내용일 것입니다. 그렇지만 약간 틀리기도 했습니다. 조금 더 정확히 쓰면 다음과 같이 표현할 수 있습니다.

* new: 객체 하나를 동적으로 할당하고, 초기화시켜 줍니다.
* delete: 객체 하나를 소멸시키고, 삭제합니다.
* new []: 객체의 배열을 동적으로 할당하고, 하나 하나를 초기화시켜 줍니다.
* delete []: 객체의 배열 하나 하나의 요소를 소멸시키고, 배열을 삭제합니다.

다시 말하면 new/new[]는 할당(allocation) + 초기화(initialization) 가 합쳐져 있고, delete/delete [] 는 소멸(destruction) + 삭제(release) 가 합쳐져 있습니다.(실은 new/new [] 에서는 좀 더 복잡한 처리가 이루어 집니다) 컴파일러가 new/new[] 또는 delete/delete[]를 만나면 자동적으로 위와 같이 작동하도록 코드를 생성해 준다는 것입니다.

이게 바로 개선된 C 로서의 C++의 특성입니다. C 로 프로그램을 작성할 경우, 할당 후, 초기화를 하지 않아서 또는 반대로 소멸과정을 거치지 않은 채로 삭제해서 발생하는 문제가 있었는데, 이 에러의 가능성을 근본적으로 줄인 C++의 특성인 거죠.

그럼 여기서 질문 하나 하고 들어가죠. 왜 C에는 malloc() 과 free() 로 모든 메모리 할당/해제를 처리했는데, C++에서는 new/delete, new []/delete [] 와 같이 객체 하나와 객체 배열을 할당/해제하는 연산자를 따로 두었을까요 ?

만약 new []/delete []가 없다면 delete 만으로 어떻게 delete [] 의 동작 방식을 구현할 수 있을까요 ? 제가 우선 생각나는 것은 new 로 할당할 때, 할당되는 메모리에 객체에 대한 서술자를 위한 메모리를 추가적으로 할당하고, 거기에 메모리에 대한 정보를 서술해 두면 될 것 같네요. 이 서술자가 있으면 그걸 보고 객체 배열 하나 하나의 요소를 소멸시킬 수 있을 겁니다.

+------------+------------+
|     n      | object x n |
+------------+------------+

n = 1 이면 single object, >1 이면 array

물론 꼭 이렇게 할 필요는 없겠지만, 대강 할당되는 메모리마다 서술자가 필요할 거라는 느낌은 드실 겁니다. 그런데 조금만 생각해 보면 굳이 객체 하나를 생성하는데 n 이라는 overhead 가 필요할까 라는 생각이 드실 겁니다. 우리 내면 깊숙이 잠재해 있는 공학도의 근성이 저걸 없애 버리고 싶은 충동을 느끼게 하지 않나요 ? 그럼 어떻게 ? 그렇죠~ new/delete, new[]/delete[]를 구분하는 거죠.

그래서, new 와 new [] 가 할당하는 메모리 배치는 약간 차이가 있을 것입니다. 그 차이는 new []는 최소한 배열의 개수를 표현하는 서술자를 추가적으로 더 할당하게 된다는 거니다. 다음과 같이요

        +------------+
new:    |   object   |
        +------------+
             +------------+------------+
new [] :     |     n      | object x n |
             +------------+------------+

컴파일러마다 구현할 수 있는 방식은 다를 수 있긴 하겠죠. So what ? 그래서 뭐가 어쩌냐구요 ? 음... 그거야 어찌 됐든 버그 없는 세상에서 행복하게 살자는 얘기죠. 그래서 여기 오늘의 중요한 본론 들어갑니다.

"new 로 할당했으면 delete 로 해제, new [] 로 할당했으면 delete []로 해제하시라"

그겁니다. 그럼 다음 코드를 실행시키면 어떤일이 일어날까요 ?

int main()
{
  int* pi1 = new int[10];
  int* pi2 = new int(10);
  // Oops!! delete []는 서술자를 보고 여러번 destruction을 수행
  delete [] pi2;
  delete pi1;                // Oops!! destruction이 한 번만 수행
  return -1;
}

말 그대로 undefined behavior 입니다.  어떻게 될지 알 수 없다는 거죠. 여러분에게 운이 따르면, 제대로 수행되는 것이고, 운이 없으면 잠자고 있는 새벽에 여러분에게 전화가 오는 거죠.

new/delete, new []/delete [] 쌍을 맞추실래요 아니면 새벽에 회사 나가서 디버깅 하실래요 ? 그냥 항상 신경 써서 맞추십시오.

이제 다음 얘기로 넘어가 보겠습니다.

(헉헉 다음 얘기는 나중에... 힘들다...)

TODO:
- set_new_handler 관련된 new 연산자의 동작 방식 설명하기
- new/delete, new []/delete [] 연산자 overloading 설명하기
- placement new 설명하기
- C++ common memory error 설명하기

소프트웨어 관련된 저의 다른 글들도 참고로 읽어 보세요.

소프트웨어는 soft 해야 제 맛이다
Flexible한 S/W 작성하기
소스코드 복사의 위험성
C++ 이야기 첫번째: auto_ptr 템플릿 클래스 소개
C++ 이야기 두번째: auto_ptr의 두 얼굴
C++ 이야기 세번째: new와 delete
C++ 이야기 네번째: boost::shared_ptr 소개
C++ 이야기 다섯번째: 내 객체 복사하지마!
C++ 이야기 여섯번째: 기본기 다지기(bool타입에 관하여)


제 글이 유익하셨다면 오른쪽 버튼을 눌러 제 블로그를 구독하세요. ->
블로그를 구독하는 방법을 잘 모르시는 분은 2. RSS 활용을 클릭하세요.
RSS에 대해 잘 모르시는 분은 1. RSS란 무엇인가를 클릭하세요.

신고
  1. JuneYin

    2007.03.09 07:28 신고 [수정/삭제] [답글]

    C++은 할때마다 머리 아파요 ㅠ
    특히 마소에서 닷넷으로 넘어가면서 뭔소린지.......

  2. 준인(2)

    2007.03.09 16:50 신고 [수정/삭제] [답글]

    그냥.... 접었죠.
    학교일이 더 급해서요;

  3. 승네군

    2007.03.11 01:47 신고 [수정/삭제] [답글]

    매번 명강의(강좌?) 잘보고 있습니다.
    (혹시라도 중간에 그만두지 마시고 쭈우우~ㄱ 계속 해 주세요 : )

  4. 김병훈

    2007.12.17 04:41 신고 [수정/삭제] [답글]

    감사합니다 네이버 지식인에서 태그 타고 왔는데 ^^;
    좋은거 배워 갑니다.

  5. 매너남

    2009.02.16 23:59 신고 [수정/삭제] [답글]

    구글에서 검색하다가 우연히 보게 되었습니다. 잘 읽고 갑니다. 건강하세요.

  6. zames

    2009.06.09 06:21 신고 [수정/삭제] [답글]

    많은 도움 되었습니다. 감사합니다 ^^

  7. sujin

    2010.06.24 01:28 신고 [수정/삭제] [답글]

    정말 많은 도움이 되고 있습니다. 감사드려요,
    이제 막 C++공부하고 있는데 여기 글 보니 재미있어 지려 합니다 ~!! +_+

    위에 있던 댓글 내용과 같이 주~욱 계속해 주세요~

  8. WithC

    2010.09.26 21:07 신고 [수정/삭제] [답글]

    잘 보고 갑니다.

    자꾸 헥갈려서 힘들었는데~

    정리가 한순간에 쏴 되는거 같아서 기분 좋아요~

    앞으로도 꾸준히 들러야 겠습니다.

  9. 나그네

    2012.12.17 17:18 신고 [수정/삭제] [답글]

    안그래도 찾고 있던 자료였는데.... 고맙습니다^^ 덕분에 많은 것을 배우고 갑니다~!

댓글을 남겨주세요.