치춘짱베리굿나이스
[Rank 5] ft_containers - Allocator 본문
Allocator 클래스
컨테이너를 하기 위해 필수로 알아야 하는 클래스이다
앞의 반복자 파트에서는 전혀 쓸 일이 없었지만 벡터나 스택 같은 컨테이너들은 기본적으로 메모리 할당을 하고 그 안에 요소들을 저장해야 하며, 내부 메서드에서 메모리 일부 할당 및 해제가 잦기 때문에 Allocator
의 사용법을 반드시 익혀야 한다
뭐 하는 녀석인지
C/C++에서는 메모리 관리를 위해서 malloc
, calloc
, free
… 와 new
, delete
를 사용했었다
특정 변수를 위한 메모리를 할당하고자 한다면 이 함수들이 편리하지만, 직접 컨테이너를 구현할 때 (ft_containers 처럼) 는 이야기가 달라진다
컨테이너 내부에서는 특정 메서드를 호출할 때마다 일정 영역만 메모리를 해제하거나 재할당하는 등 다양하고 세밀한 동작을 요구하므로, new
/ delete
만으로는 한계가 있는 것이다
예를 들면, 벡터의 용량 (capacity
) 을 늘리거나 줄일 때 (reserve
), 벡터의 크기 (size
) 를 늘릴 때 (resize
) 는 인자로 받은 크기만큼 메모리를 재할당해 주어야 하는데, new
만으로는 이러한 조작이 애매해진다
new
는 메모리 할당 뿐만 아니라 초기화도 동시에 진행하므로, 메서드를 통해 new
를 자주 호출하게 되면 성능의 저하도 발생할 것이다
컨테이너를 만들기 위해선 allocator
를 쓰자
Allocator 클래스 구문
template <class T>
class allocator
- 템플릿 클래스로, 어떤 자료형 (클래스) 의 메모리 공간을 할당 / 해제할 것인지 나타내는 클래스
T
를 갖는다 allocator
는<memory>
헤더를 include하여 사용할 수 있다
타입 정의
pointer
T
의 포인터 타입이다
reference
T
의 참조 타입이다
const_pointer
T
의 상수 포인터 (constant pointer) 타입이다
const_reference
T
의 상수 참조 (constant reference) 타입이다
size_type
unsigned int
형식으로, allocator
가 할당할 수 있는 메모리 영역의 단위 길이를 나타낸다
value_type
allocator
가 다루는 타입으로, T와 같다
멤버 함수
생성자
allocator(); // 생성자
allocator(const allocator<T>& instance); // 복사 생성자
template <class T_>
allocator(const allocator<T_>& instance); // 복사 생성자
- 새로운
allocator
객체를 생성한다
address
pointer address(reference val) const;
const_pointer address(const_reference val) const;
- 인자로 들어온 요소
val
의 주소를 반환한다
allocate
pointer allocate(size_type count, const void* _Hint = 0);
count
개의T
타입 메모리 영역을 새롭게 할당한다 (메모리 크기:count
*sizeof(T)
)_Hint
는 근처의 메모리 주소를 넣을 수 있으며, 특정 주소의 근처에 새로운 메모리를 할당하고 싶다면 힌트로서 메서드에 제공할 수 있다_Hint
의 기본값은 0 (널 포인터) 이므로, 굳이 2번째 인자를 제공하지 않아도 자동으로 초기화된다_Hint
가 제공되면, 최대한 해당 주소에 가까운 곳에 새로운 메모리를 할당한다
- 반환값 (
pointer
타입) 은 새롭게 할당한 메모리 영역의 첫 번째 요소 주소이다
construct
void construct(pointer p, const_reference val);
- 메모리는 할당되었지만 초기화되지 않은 메모리 주소
p
에T
타입의 객체를 생성 (Construct) 한다 - 주소
p
에new
키워드를 이용하여T
생성자를 호출한 것과 똑같이 동작한다- 생성자의 인자로
val
이 들어간다 (복사 생성자 호출) new((void *)p) T(val)
과 동작이 같다
- 생성자의 인자로
deallocate
void deallocate(pointer p, size_type n);
- 메모리 주소
p
가 가리키는 영역을 해제한다- 주소
p
부터 총n
개의T
타입 메모리 영역을 해제한다 (메모리 크기:n
*sizeof(T)
)
- 주소
- 다만 이 함수를 호출하는 것이 내부에 초기화된 객체의 소멸자를 호출하지 않음에 주의하자
destroy
void destroy(pointer p);
- 메모리 주소
p
가 가리키는 영역의 소멸자를 호출한다 deallocate
와 반대로, 이 함수는 메모리 영역 해제를 도와주진 않는다
max_size
size_type max_size() const throw();
- 현재 할당 가능한
T
타입의 메모리 개수allocate
등에서 사용되는count
의 최대값으로, 이 이상의 메모리를 할당받을 수 없다allocate(count, 0)
이 성공할 수 있는count
의 최대값이라고 이해하자
비 멤버 함수
operator==
template <class T1, class T2>
bool operator==(const allocator<T1>& lhs, const allocator<T2>& rhs) throw();
==
연산자에 대한 오버로드- 두
allocator
인스턴스를 비교하…긴 하는데, 기본allocator
는 무상태성을 띄므로 결과적으로 모든allocator
는 같다- 따라서 항상
true
를 반환한다
- 따라서 항상
operator!=
template <class T1, class T2>
bool operator!=(const allocator<T1>& lhs, const allocator<T2>& rhs) throw();
!=
연산자에 대한 오버로드==
오버로드와 마찬가지로,allocator
의 무상태성 때문에 모든allocator
이 같음을 보장한다- 따라서 항상
false
를 반환한다
- 따라서 항상
참고 자료
https://en.cppreference.com/w/cpp/memory/allocator
https://cplusplus.com/reference/memory/allocator/
https://learn.microsoft.com/en-gb/cpp/standard-library/allocator-class?view=msvc-170#address
'42 > 42s Cursus' 카테고리의 다른 글
[Rank 5] ft_containers - std::stack (0) | 2023.02.18 |
---|---|
[Rank 5] ft_containers - std::vector (4) | 2023.02.04 |
[Rank 5] ft_containers - std::reverse_iterator (0) | 2023.01.17 |
[Rank 5] ft_containers - explicit 키워드 (0) | 2023.01.13 |
[Rank 5] ft_containers - std::iterator_traits (0) | 2023.01.11 |