new에 대해서 궁금한게 있습니다.
글쓴이: bangkert89 / 작성시간: 목, 2012/12/20 - 8:37오전
서문이 좀 길지만 읽어주시면 감사하겠습니다.^^
지금 EffectiveC++를 보면서 공부하고 있습니다.
메모리 관리 챕터에 보면 memoryPool에 대해서 설명되어 있어
코드를 만들어 보면서 공부하는 중입니다.
아래가 책을 참조해서 만든 코드구여
여러 클래스에서 사용되니까 템플릿으로 바꿔놨습니다.
template<class T> class Pool { public: Pool(int BlockSize = 512); Pool<T> * InitFreeList(); void * Alloc(size_t size); void Free(void * deadMem, size_t size); ~Pool(); void SetBlockSize(int BlockSize); private: union { T * m_Rep; Pool<T> * m_Next; }; static int BLOCK_SIZE; static Pool<T> * HeadOfFreeList; static Pool<T> * OriginalHead; }; template<class T> int Pool<T>::BLOCK_SIZE; template<class T> Pool<T> * Pool<T>::HeadOfFreeList; template<class T> Pool<T> * Pool<T>::OriginalHead; template<class T> Pool<T>::Pool(int BlockSize = 512) { BLOCK_SIZE = BlockSize; HeadOfFreeList = NULL; OriginalHead = InitFreeList(); } template<class T> Pool<T> * Pool<T>::InitFreeList() { Pool<T> * NewBlock = static_cast<Pool<T> *>(::operator new(BLOCK_SIZE * sizeof(Pool<T>))); for (int i = 0;i < BLOCK_SIZE-1;++i) { NewBlock[i].m_Next = &NewBlock[i+1]; } NewBlock[BLOCK_SIZE-1].m_Next = NULL; HeadOfFreeList = NewBlock; return HeadOfFreeList; } template<class T> void * Pool<T>::Alloc(size_t size) { if (size != sizeof(T)) { return ::operator new(size); } Pool<T> * pTemp = HeadOfFreeList; if (pTemp) { HeadOfFreeList = pTemp->m_Next; } else { pTemp = InitFreeList(); HeadOfFreeList = pTemp->m_Next; } return pTemp; } template<class T> void Pool<T>::Free(void * deadMem, size_t size) { if (deadMem == NULL) { return; } if (size != sizeof(T)) { ::operator delete(deadMem); return; } else { Pool<T> * pTemp = static_cast<Pool<T> *>(deadMem); pTemp->m_Next = HeadOfFreeList; HeadOfFreeList = pTemp; } } template<class T> Pool<T>::~Pool() { ::operator delete(OriginalHead); } template<class T> void Pool<T>::SetBlockSize(int BlockSize) { BLOCK_SIZE = BlockSize; }
코드를 만들고 사용해보니 3가지 문제가 있었는데
1. 메모리주소를 받아서 일일이 형변환을 해줘야한다.
2. 항상 호출할때마다 ClassName(Pool을사용하는 클래스)::operator new(size)를 작성해야한다.
3. 생성자 및 소멸자를 일일이 호출해줘야한다.
그래서 new Type 형식처럼 바꿔보려고 합니다.
new Type형식이 어떤식으로 실행되는지 보기위해
int * temp = new int;에 brake point를 걸고
디버깅해서 따라가보면 ::operator new와 new Type이 똑같이 아래에 함수를 호출하는 겁니다.
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
또한 리턴값도 둘다 void * 형태로 리턴됩니다.
!!!!!!!!여기서 질문!!!!!!!(서문이 좀길죠... ㅠㅠ)
new Type이 코드실행이 종료된 후에 리턴값인 void *를 가지고
어떻게 형변환을 하고 생성자를 호출하는 건가요... 단 한줄의 코드없이.....
또 같은 함수를 호출해서 처리를 하는데 왜 결과가 다른거죠.......
처음 올리는 질문이라.. 정신이없을 겁니다.. 친절한 답변 부탁드립니다^^
Forums:
Effective C++을 공부 중이시라면 아마도
Effective C++을 공부 중이시라면 아마도 본문에 설명이 되어있지 않던가요?
Type* p = new Type(); 과 같이 사용하실 경우 실제로는 두 단계가 수행되게 됩니다.
따라서 operator ::new()를 오버로딩하실 경우 단계 1의 행동을 오버로딩하시게 되는 것이고, 메모리를 할당하는 작업에 있어서는 타입에 관계없이 할당된 메모리의 위치를 넘겨주는 역할만 수행하면 되니까 void* 로 리턴을 하는 것입니다.
사실 두번째 줄의 replacement new 자체도 메모리를 할당하지 않는 operator이긴 하지만 이해하시는데에는 무리가 없을 것 같습니다.
헛..
실력자 분이시니까...
내부적으로 형변환이 되고 생성자가 호출되는지는 알겠어요..
근데 Type * p = new Type;여기서 젤먼저 수행하는게
메모리를 void *로 할당하고 리턴해주잖아요
디버그를 해보면 함수가끝나고 메인으로 돌아오거든요..
그후에 void *를 가지고 Type * p = new Type; 처럼
코드한줄없이 어떻게 메인함수에서
형변환을 하고 생성자를 호출하는 거죠...........
글고 ::operator new 나 new Type이나 같은 함수를 호출하는데...
ㅠㅠ 어디서 그런 차이가 발생되는지가 궁굼해서 질문올림니다...
언어 자체에 내재된 기능입니다. 보여드린 코드가
언어 자체에 내재된 기능입니다. 보여드린 코드가 라이브러리 어딘가에 구현되어있어 디버거로 확인할 수 있는 것이 아니라, 컴파일러 스스로 저러한 과정을 수행하도록 동작한다고 생각하시면 됩니다.
학.. 어렵네요.. ㅠㅠ
답변 감사합니당 ><
저건 너무 어렵고 복잡해서 모르겠지만
이렇게 하면. 비슷하지 않을까 생각됩니다.
데이터 형의 크기를 알면. 접근자가 데이터를 가져 올 수도 있고. 형변환도 가능합니다.
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
중복글
.
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
댓글 달기