new 및 delete를 사용할 때는 형태를 반드시 맞추자.


string* sArray = new string[100];

...

delete sArray;


new

1. 먼저 operator new 에 의해 메모리가 할당된다.

2. 할당된 메모리에 한 개 이상의 생성자가 호출된다.


delete

1. 기존 할당된 메모리에 한개 이상의 호멸자가 호출된다.

2. operator delete에 의해 메모리가 해제된다.




여기서 핵심은 삭제되는 포인터 sArray는 객체 하나만

가리키느냐, 객체 배열을 가리키고 있느냐 이다.


단일 객체와 객체 배열은 메모리 배치구조가 다르다.

객체 배열은 배열원소의 개수에 대한 정보를 가지고 있다.

하지만 단일 객체는 이러한 정보를 가지고 있지 않다.




따라서 이 둘의 배치구조가 다르기 때문에 delete를 사용해

메모리를 해제해 줄때, 배열 크기 정보가 있다는 것을

알려줘야 한다. 이 때 delete[] 를 써주면 이 포인터가

배열을 가리키고 있구나 라고 가정하게 된다.




string sPtr1 = new string;

string sPtr2 = new string[10];


delete sPtr1; --> 단일 객체로 인식하고 한 개를 삭제.

delete[] sPtr2;  --> 배열의 원소 개수 정보를 넘겨줌




주의점

1. sPtr1에 delete[]를 쓸 경우

delete는 sPtr1 앞쪽의 메모리 몇 바이트를 읽고

이 것을 배열 크기라고 해석하고, 배열 크기에

해당하는 만큼 소멸자를 호출하기 시작한다.


2. sPtr2에 delete를 쓸 경우

sPtr2를 단일 객체로 인식하고 소멸자를

단 한번만 호출하게 된다. 소멸자가 없는

기본제공 타입이라 해도 이들의 배열에 대해

[]를 쓰지 않으면 미정의 동작이 나타난다.




new 표현식에 []를 썼으면, 여기에 대응 되는

delete 표현식에도 []를 써야 한다.

반대로 new에서 []를 쓰지 않았으면

delete 에도 []를 쓰지 않으면 된다.




동적 할당된 메로리에 대한 포인터를

멤버 변수로 가지고 있는 클래스라면

이 클래스에서 제공하는 모든 생성자에서는

new 형태를 똑같이 맞춰줘야 한다.

왜?? 소멸자에서 어떠한 형태의 delete를

써야할지 구분하기 어렵기 때문이다.




주의점

배열을 typedef로 사용할 경우

typedef string Address[10];

...

stinrg *p = new Address;

어떠한 delete를 써야할까?

혼란의 여지가 다분하다.


1. delete p --> 배열인데 객체 하나만 지운다.

2. delete[] p --> 제대로 동작한다.


배열을 typedef로 만들지 말자. --> 알아보기 힘들다.

대신 stiring 또는 vector 같은 클래스 템플릿을 잘 활용하자.

잘 활용한다면 동적 할당된 배열이 필요해질 경우가 거의 없다.




POINT!!

1. new와 delete의 형식을 맞추자.

+ Recent posts