정진하는중

[C++] new [], delete []

 

1. 서론

new, delete가 malloc, free와 다른 점은 메모리 할당시 클래스의 객체를 타입으로 넘길 때,

생성자와 소멸자를 호출시키는 점을 알고 있습니다.

 

기본 타입을 제공할 시, 메모리 할당만 받아 그 주소를 주고받는 과정은 같습니다.

 

그러나 new [], delete []는 내부적인 동작 과정이 다르기 때문에, 반드시 짝을 맞춰서 사용해야 합니다.

또한 delete [] 를 통해 소멸자를 어떻게 호출하는지 알 수 있습니다.

 

그 이유와 과정을 동작 과정을 살피면서 알아보겠습니다.

 

2. new[], delete [] 동작 과정

 

이러한 코드가 있을 때, 클래스 객체를 new [] 를 통해 동적 할당을 진행할 시

 

class Test
{
public:
	Test() { std::cout << "생성자" << std::endl; }

	~Test() { std::cout << "소멸자" << std::endl; }
};

int main() 
{
	
	Test* ptr = new Test[4];

}		// (VC, 64bit, Debug 모드 환경)

 

malloc, 단일 객체 new와의 차이점은 힙 영역에 메모리를 추가로 할당하여 등록합니다.

 

무슨 말이냐면..

 

8바이트를 추가로 할당 (그림의 8은 메모리 크기입니다, 객체의 개수인 4가 저장됩니다.)

 

이런 식으로 객체 4개의 사이즈인 16바이트 + 객체의 주소를 저장할 8바이트 변수를 추가로 할당 받습니다.

( 32bit 환경에서는 4바이트, 64bit 환경에서는 8바이트 )

 

ptr로 반환받는 값은 [0]에 해당하는 주소를 반환합니다.

이를 통해 ptr, &ptr[0] 은 동일하며 인덱스를 통해 접근할 때 

객체의 멤버에만 접근하며, 객체 배열의 개수를 저장하는 영역은 일반적으로는 모르고 사용할 수 있습니다. 

 

 

 

D8로 끝나는 번지수가 &ptr[0] / 64bit 기준 8바이트를 추가로 할당 받아 객체 개수를 저장

 

메모리를 통해 확인하면 객체의 개수 4를 

D8로 끝나는 번지수(&ptr[0]) 위로 8바이트 변수를 추가로 할당 받아 저장하고 있는 모습을 볼 수 있습니다.

( 32bit 환경에서는 4바이트 ) 

 

  • 왜 이런 구조를 사용할까요?

 

delete [] 과정에서 객체의 소멸자를 호출하는 과정에서 활용됩니다.

 

또한 이러한 이유로 new [] 할당을 통해 반환받은 메모리 시작 번지수는 반드시 delete [] 를 통해 반납하여야 합니다.

delete [] 를 통해야 객체의 개수를 저장하고 있는 번지수를 참조하여 소멸자를 호출시키고

힙에 등록된 시작 번지수에 맞게 반환할 수 있습니다.

 

기본 타입을 new [] 를 통해 할당 받을 시,  delete를 통해도 반납될 수 있지만 객체 배열인 경우 반납되지 않습니다. 

 

이를 혼동하면 안 되는 정확한 이유를 알아보았습니다. 

 

 

 

 

 

참조

https://dataonair.or.kr/db-tech-reference/d-lounge/technical-data/?mod=document&uid=235893/

 

C++ 프로그래밍 : 동적 메모리 할당과 소멸자의 관계

C++ 프로그래밍 동적 메모리 할당과 소멸자의 관계 C/C++를 비롯해 자바 프로그래밍의 경우 필수적으로 동적 메모리 할당을 해야만 한다. 할당된 메모리를 처리할 때는 차이가 발생한다. 자바의

dataonair.or.kr

 

 

 

 

 

 


댓글