C++의 연산자는 내장 연산자가 아닐 수 있다

C++ 의 연산자들은 overloading 될 수 있고, 이에 따라 동작이 변할 수 있다. 내가 몇 일전에 KLDP 질문 글에 답변을 올리다가 저지른 실수를 적어보겠다.

사실 질문글 자체는 간단했는데, C-style 문자열을 위한 메모리를 동적으로 할당하는데 strlen 으로 bytes 길이를 구한게 아니라 sizeof(char* type pointer)로 포인터의 크기를 구한 후에 문자열을 복사해서 런타임 오류가 발생하는 문제였다. 그래서 “strlen( )” 쓰세요로 답변 끝.

문제는 여기에서 시작. 다른 한 명이 “delete로 char* 배열을 제거할 때와, delete[] 로 배열을 제거할 때 차이가 나지 않았다” 라고 추가 질문을 해서, “내장 타입에선 차이가 없다” 라고 답변을 달았다. 사실 그 근거는 다음과 같다고 생각했다:

  • delete[] 연산자의 동작은 크게 2단계
    1. 배열에 속한 각 항목에 대해서 소멸자(destructor; dtor)를 호출하고,
    2. 전체 배열의 메모리 공간을 해제한다.
  • 그런데 int, char 같은 내장된 데이터 타입은 소멸자가 아무 일도 하지 않는다.
  • 따라서 두 가지 연산자 (delete와 delete [])를 사용하는 차이가 없다.

사실이 아닙니다.

다른 분이 댓글로 알려주신 것이지만, C++ faq-lite에 나와있는 것 같은 경우엔 의도대로 동작하지 않습니다.

메모리를 할당하는 방식을 바꾸기 위해 custom memory allocator를 쓰는 경우 “재앙"을 보게 됩니다(=UB일 수 있음)

C++의 연산자가 눈에 보이는 그 것이 아닐 수 있다는 사실을 되새기게 되었음…