Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++의 delete[]는 어떻게 피연산자 배열의 크기를 알아낼까?

C++에서 new 연산자는 동적 메모리 할당을 담당하며, 할당된 변수는 힙(heap) 영역에 배치됩니다. 반대로 delete[] 연산자는 배열 형태로 할당된 이 메모리를 힙에서 해제하는 역할을 합니다.

그렇다면 delete[]는 자신이 해제해야 할 배열의 크기를 어떻게 알 수 있을까요? 핵심은 new[]가 메모리를 할당할 때 실제 배열 본체 앞에 별도의 관리 영역(오버헤드, 흔히 쿠키(cookie)라고 부름)을 추가로 확보하고, 그곳에 생성한 요소의 개수를 기록해 둔다는 점입니다. delete[]는 이 개수 정보를 읽어 각 요소의 소멸자를 정확한 횟수만큼 호출한 뒤 전체 메모리를 해제합니다. 덕분에 프로그래머가 배열 크기를 직접 넘겨 주지 않아도 안전하게 해제할 수 있습니다.

단, new와 delete[], new[]와 delete는 반드시 짝을 맞춰 사용해야 합니다. 짝이 어긋나면 미정의 동작(undefined behavior)이 발생할 수 있습니다.

예제 코드

#include <iostream>
using namespace std;
int main() {
   int B = 4;
   int A = 5;
   int** a = new int*[B];
   for(int i = 0; i < B; ++i)
      a[i] = new int[A];
   for(int i = 0; i < B; ++i)
      for(int j = 0; j < A; ++j)
         a[i][j] = i;
   for(int i = 0; i < B; ++i)
      for(int j = 0; j < A; ++j)
         cout << a[i][j] << endl;
   for(int i = 0; i < B; ++i)
      delete [] a[i];
   delete [] a;
   return 0;
}

위 예제는 4행 × 5열 크기의 2차원 배열을 동적으로 생성하고, 각 행의 인덱스 값으로 초기화한 뒤 출력하는 프로그램입니다. 해제 시에는 먼저 행(row) 개수만큼 각 행을 delete[]로 해제한 후, 마지막에 포인터 배열 자체를 delete[]로 해제해야 메모리 누수 없이 깔끔하게 정리됩니다.

실행 결과

0
0
0
0
0
1
1
1
1
1
2
2
2
2
2
3
3
3
3
3