c++ 생각하기 3.

반응형


1. new, delete, operator new, operator delete, placement new
new와 operator new의 차이?
new의 동작은 메모리의 할당, 생성자를 호출하여 초기화 수행이다.
operator new의 동작은 메모리의 할당.

new 연산자는 우리가 바꿀 수 있는 부분이 아니다.
우리가 바꿀 수 있는 부분은 객체를 담을 메모리를 할당하는 방법 뿐이다.
new 연산자는 메모리 할당을 위해 어떤 함수를 호출하는데 이 함수를 오버로딩 하는 것이다.
이것이 operator new이다.

즉 우리는 생성자까지 호출되어 초기화된 객체만을 받을 수 있는 것이다.
왜냐하면 객체는 딱 한번 초기화 될 수 있기 때문이다.
하지만 할당받은 미초기화 메모리가 있다면 이를 객체형태로 만들고 싶을수도 있다.
이럴때 쓰는 것이 operator new의 특별판인 메모리 지정 new(placement new)라고 불리는 함수이다.

class MgPlacNew
{
public:
 MgPlacNew(int iSize) {}
};

MgPlacNew* constructPlacNewInBuf(void* buf, int iSize) { return new MgPlacNew(iSize); }


int _tmain(int argc, _TCHAR* argv[])
{
 void* pBuf = NULL;
 MgPlacNew* pObj = constructPlacNewInBuf(pBuf, 5);
 return 0;
}

눈여겨 봐야 할 곳은 PlacNew객체를 pBuf로 지정되는 메모리에 생성한 후에 해당 포인터를 반환한다는 것이다.
즉, 객체를 특별한 주소공간이나 원하는 메모리에 담아 둘 수 있다.
말 그대로 메모리 지정 new는 객체의 데이터를 넣어 둘 메모리 주소를 넘겨줘서 원하는 메모리에 지정하여 객체를
사용한다고 보면 될 것 같다.

결론 : 어떤 객체를 힙에 생성할 경우 -> new 사용. (메모리 할당 + 생성자 호출)
         메모리 할당만 하고 싶은 경우 -> operator new 함수 사용. (생성자가 호출되지 않는다)
         힙에서 직접 메모리를 가져오는 게 아니라 내가 지정한 메모리를 사용할 경우 -> 메모리 지정 new 사용.

delete pObj; 또한
소멸자 호출 pObj->~MgPlacNew();
메모리 해제 operator delete(pObj);

그런일은 잘 없지만 미초기화된 메모리가 필요한 경우, operator new와 operator delete가 사용된다.
지정 new로 넘겨받은 미초기화된 메모리는 직접 해제해야 한다.

2. 예기치 못한 종료로 인한 메모리 누수
지정 new로 넘겨받은 미초기화된 메모리는 직접 해제해야 한다.
int iValue = 50;
while(i0 < iValue--)
{
    MgObject* pObj = CalcTransformObject(iValue);
    pObj->Apply();
    delete pObj;
}

만약 Apply중 예외가 발생한다면 아래의 delete는 수행되지 못하고 그냥 지나치게 되고 결국 메모리 누수.
try catch를 써도 되지만 문은 내 눈에 지독히도 익숙해 지지 않는다. (템플릿도 그렇고.ㅜㅜ.)

이럴때 스마트 포인터(smart pointer)를 쓰면 된다.
유효범위르 벗어나면 자신이 가리키는 메모리를 삭제한다.

이런것도 있네...
className(const className&);
className& operator=(const className&);
객체의 대입과 복사를 명시적으로 금지.
동적 할당 리소스는 객체로 포장하자

TAGS.

Comments