KoreanFoodie's Study
Effective C++ | 항목 50 : new 및 delete 를 언제 바꿔야 좋은 소리를 들을지를 파악해 두자 본문
Tutorials/C++ : Advanced
Effective C++ | 항목 50 : new 및 delete 를 언제 바꿔야 좋은 소리를 들을지를 파악해 두자
GoldGiver 2022. 10. 25. 16:34
C++ 프로그래머의 필독서이자 바이블인, 스콧 마이어스의 Modern Effective C++ 를 읽고 기억할 내용을 요약하고 있습니다. 꼭 읽어보시길 추천드립니다!
항목 50 : new 및 delete 를 언제 바꿔야 좋은 소리를 들을지를 파악해 두자
핵심 :
개발자가 스스로 사용자 정의 new 및 delete 를 작성하는 데는 여러가지 이유가 있다. 여기에는 수행 성능 향상, 힙 사용 시의 에러 디버깅, 힙 사용 정보 수집 등의 목적이 포함된다.
operator new 와 operator delete 를 바꾸는 가장 흔한 세 가지 이유를 한 번 보자.
- 잘못된 힙 사용을 탐지하기 위해 : 데이터 오버런(overrun) 및 언더런(underrun) 을 탐지하기 위해 탐지용 바이트를 추가로 할당할 수 있다.
- 효율을 향상시키기 위해 : 힙 단편화 등 실행환경에 맞게 커스터마이징
- 동적 할당 메모리의 실제 사용에 관한 통계 정보를 수집하기 위해 : 로그 수집 등
경계 표지 패턴의 간단한 구현을 한 번 보자.
static const int signature = 0xDEADBEEF;
typedef unsigned char Byte;
void*operator new(std::size_t size) throw(std::bad_alloc)
{
using namespace std;
// 경계 표지 2개를 앞뒤에 붙일 수 있을 만큼 메모리를 확장
size_t realSize = size + 2 * sizeof(int);
void *pMem = malloc(realSize);
if (!pMem) throw bad_alloc();
// 메모리 블록의 시작 및 끝부분에 경계 표지를 기록
*(static_cast<int*>(pMem)) = signature;
*(reinterpret_cast<int*>(static_cast<Byte*>(pMem) + realSize - sizeof(int))) = signature;
// 앞쪽 경계 표지 바로 다음의 메모리를 가리키는 포인터를 반환
return static_cast<int*>(pMem) + sizeof(int);
}
위 구현은 operator new 에 쓰이는 관례(new 처리자 호출 루프 구현)이 지켜지지 않았지만, 자세한 건 항목 51에서 다루기로 한다.
사실 위의 문제는, 바이트 정렬(alignment) 의 문제를 갖고 있다. 여기서는 경계 표지를 4바이트(int 의 사이즈) 로 설정해서 포인터를 경계 표지 시작지점 + 4 인 곳을 리턴한다. 하지만 해당 operator new 를 사용하는 녀석이 double 을 할당하고, 각각의 주소값을 8바이트로 잡는 경우, 문제가 생길 수 있다.
이외에도 추가적인 문제가 생길 수 있지만, 사용자 operator new 와 operator delete 를 만들 때는, 다음과 같은 이유로 만드는 것인지를 잘 고려해 보자.
- 할당 및 해제 속력을 높이기 위해
- 기본 메모리 관리자의 공간 오버헤드를 줄이기 위해
- 적당히 타협한 기본 할당자의 바이트 정렬 동작을 보장하기 위해 : double 시에는 8바이트 정렬을 보장해야 프로그램 성능이 좋다
- 임의의 관계를 맺고 있는 객체들을 한 군데에 나란히 모아 놓기 위해
- 그때그때 원하는 동작을 수행하기 위해
'Tutorials > C++ : Advanced' 카테고리의 다른 글
Effective C++ | 항목 52 : 위치지정 new 를 작성한다면 위치지정 delete 도 같이 준비하자 (0) | 2022.10.26 |
---|---|
Effective C++ | 항목 51 : new 및 delete 를 작성할 때 따라야 할 기존의 관례를 잘 알아 두자 (0) | 2022.10.26 |
Effective C++ | 항목 49 : new 처리자의 동작 원리를 제대로 이해하자 (0) | 2022.10.25 |
Effective C++ | 항목 48 : 템플릿 메타프로그래밍, 하지 않겠는가? (0) | 2022.10.25 |
Effective C++ | 항목 47 : 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자 (0) | 2022.10.25 |
Comments