reserve는 필요 없이 메모리가 재할당되는 것을 막아 주다.

vector와 string에 있어서의 메모리 증가는 재할당이란 과정을 거쳐서 이루어 진다.(현재 사이즈의 증가가 아닌 컨테이너에서 할당해놓은 메모리가 부족해 질때)


  1. 컨테이너의 현재 용량의 몇배가 되는 메모리 블록을 새로 할당 (일반적으로 2배)
  2. 컨테이너가 가지고 있었던 메모리에 저장된 모든 요소 데이타(객체)를 새 메모리에 복사
  3. 원래 메모리에 저장된 모든 객체를 소멸
  4. 원래의 메모리를 해제
라는 과정을 거친다.
이런 오버헤드를 줄이기 위해서 필요한 만큼의 메모리를 미리할당하고 데이타를 삽입한뒤 관리하는 방식을 사용할수 있다. 이때 사용하는것이 reserve 이다.
예를 들어
vector<int> v;
for(int i=0; i<1000; i++) v.push_back(i);
라는 코드는 루프를 도는 동안 대략 10번 정도의 메모리 재할당이 일어나게 된다.(메모리크기를 2배씩 잡을때) 하지만 reserve를 사용하면 이런 불필요한 메모리 재할당을 막을수 있다.
vector<int> v;
v.reserve(1000);
for( int i=0; i<1000; i++ ) v.push_back(i);
위의 코드는 루프를 도는 동안 메모리 할당이 한번도 일어나지 않게 된다.
그리고 size와 capacity의 관계를 잘 생각해보면 요소 삽입시 vector나 string에서 재할당이 일어나는 시기를 예측할수 있다.
string s;

if( s.size() < s.capacity() ) s.push_back(‘X’);

정리하면 reserve를 이용해서 불필요한 메모리 재할당을 피하는 방법은 두가지 정도 이다.

  • 컨테이너에 저장될 요소의 개수를 미리 파악해서 정확한 reserve 호출
  • 컨테이너에 저장될 최대 요소의 개수를 할당하고 요소 삽입후 남는 메모리를 삭제 (EffectiveSTL17 을 참고)





참고

  • size() : 현재 컨테이너에 들어있는 요소의 개수
  • capacity() : 현재 컨테이너에 재할당없이 추가할수 있는 요소의 개수
  • resize(size_t n) : 컨테이너의 요소의 개수를 n으로 변경. 만약 현재 컨테이너의 개수가 n보다 크다면 n이후의 요소들은 삭제, 크다면 n크기로 재할당하고 뒤에 남는 공간은 요소 객체의 기본생성자로 생성해 채워 놓는다.
  • reserve(size_t n) : 컨테이너의 용량을 최소 n으로 맞춘다. 현재의 capacity()가 더 작다면 n의 크기로 재할당을 하며, 크다면 아무것도 하지 않는다. (이미 할당된 메모리의 공간을 줄이는 일이 일어날수도 있지만 삽입된 데이타를 줄이는 일은 없다.)

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다