본문 바로가기
42/42cursus

[ft_containers] 3. std::allocator 사용하기

by jaemjung 2022. 7. 12.

보통 c++에서는 동적으로 메모리 할당을 해주기 위해서 new 연산자를, 할당해준 메모리를 해제해주기 위해서는 delete 연산자를 사용하지만, container를 직접 구현할 때 new와 delete연산자를 사용하게 되면 문제가 될 수 있다.

 

new 연산을 사용하면

  1. 힙에 메모리 공간 할당
  2. 할당된 공간에 저장하고자 하는 객체의 생성자 호출
  3. 객체의 모든 요소 초기화

의 과정을 거치게 되는데, 컨테이너처럼 자료의 생성과 소멸이 빈번하게 일어나게되는 경우 객체의 요소를 초기화 하는 과정에서 불필요한 연산이 많이 일어날 수 있게 된다.

 

c++에는 c의 malloc과 free처럼 보다 직접적인 메모리 할당을 할 수 있도록 만들어진 인터페이스 객체 allocator가 있으며, 이는 <memory> 헤더를 인클루드하면 사용할 수 있다.

 

allocator에서는 주로 다음 4개의 함수를 주로 사용하게 된다.

 

tempalte <class T>
class allocator {

    typedef size_t           size_type;
    typedef ptrdiff_t        difference_type;
    typedef T                value_type;
    typedef T*               pointer;
    typedef T&               const_reference;
//...
    pointer	allocate(size_type n, allocator<void>::const_pointer hint=0);
    void	deallocate(pointer p, size_type n);
    void	construct(pointer p, const_reference val);
    void 	destroy(pointer p);
//...
};

 

1. allocate

초기화되지 않은 메모리 공간을 할당한 후 할당된 공간의 시작 주소를 리턴하는 함수이다.

파라미터로 들어가는 n은 할당하고자 하는 바이트가 아닌 할당하고자 하는 객체의 갯수이다. 

2. deallocate

할당된 메모리 공간을 해제하는 함수이다.

파라미터로 pointer와 n을 받게 되는데, 포인터는 해제할 공간의 시작주소, n은 해제할 객체의 갯수이다.

3. construct

allocate로 할당을 받은 공간에 객체를 저장하는 함수이다.

파라미터로 저장하고자 하는 공간의 포인터 및 저장하고자 하는 객체의 참조자를 받는다. 이 함수를 사용하지 않고 초기화되지 않은 공간에 참조연산자 *를 사용하여 값을 대입할 경우 에러가 발생한다.

4. destroy

할당받은 공간에 생성한 객체를 소멸시키는 함수이다.

즉, 파라미터로 들어온 포인터에 위치한 객체의 소멸자를 호출하는 것!

destroy를 해주지 않고 공간을 deallocate 해버리면 각 요소에 저장된 객체는 사라지지만, 사라진 객체가 가리키던 객체는 해제되지 않고 남아있어 메모리 누수가 날 수 있다.

 

allocator를 이용한 객체의 할당은 반드시 allocate->construct의 순서로 이루어져야하며, 객체의 해제는 반드시 destroy->deallocate의 순서로 이루어져야한다.

댓글