[C++] std::vector의 resize와 reserve의 차이점

size와 capacity의 차이점

vector의 멤버 함수인 size는 vector의 원소 개수를 반환하는 함수입니다.

또한, 이 함수는 모든 컨테이너의 기본 인터페이스이기도 합니다.

 

그렇지만, capacity는 vector 컨테이너에만 있는 독특한 함수입니다.

이 함수가 하는 일은 현재 컨테이너가 저장할 수 있는 원소의 개수를 알려주는 것입니다.

이를 통해서, vector는 원소의 개수가 늘어나는 경우에도, 잦은 메모리 재할당 횟수를 줄일 수 있습니다.

 

size와 capacity의 관계

 

아래의 예문은 vector에 원소를 추가할 때마다, 원소의 개수와 용량( capacity )을 출력하고 있습니다.

void print( const vector<int>& vec){

    int size = vec.size();
    int cap = vec.capacity();
    cout << "size: " << size << ", capacity: " << cap << endl;
    cout << endl;
}

int main(){

    vector<int> vec;
    
    vec.push_back(1);
    print(vec);

    vec.push_back(2);
    print(vec);

    vec.push_back(3);
    print(vec);

    vec.push_back(4);
    print(vec);

    vec.push_back(5);
    print(vec);
}

▼출력

size: 1, capacity: 1

size: 2, capacity: 2

size: 3, capacity: 4

size: 4, capacity: 4

size: 5, capacity: 8

위에서 보았듯이, 벡터는 원소의 개수를 늘릴 때마다, 원소를 담을 메모리를 할당해야 합니다.

그런데, 매번 메모리를 재할당하는 하는 비용은 상당히 큽니다.

 

이뿐만이 아니라, 기존의 원소들을 새로이 할당한 장소에 옮겨 담아야 합니다. 

이 과정에서 각 원소를 복사를 하던 이동( move semantics )을 하던 역시 만만치 않은 비용이 듭니다.

 

따라서, vector는 내부적인 알고리즘을 통해, 한번 할당할 때 적절한 메모리를 한꺼번에 할당해 버립니다.

그래서, 위에서 보면 5번째 원소를 위한 메모리를 할당할 때, 용량이 8이 된 것을 볼 수 있습니다.

 

이제, 다음에 6번째 원소를 추가하더라도, 새로운 메모리 할당 과정을 건너뛸 수 있게 될 것입니다.

 

참고로, max_size 함수는 컨테이너가 가질 수 있는 원소의 최대 개수를 반환합니다.

( 이 최대 개수는 컴파일러의 구현에 따라 다릅니다. )

 

그러므로, 다음과 같은 관계는 항상 참입니다.

$ size()~  \leq ~ capacity()~  \leq ~max~size()$

또한, max_sizesize와 마찬가지로, 모든 컨테이너가 가진 인터페이스 함수입니다.

 

resize와 reserve의 차이점

이름에서 알 수 있듯이, resize원소의 개수를 변경합니다.

만약, 현재가진 원소의 개수보다 더 큰 원소의 수를 입력하면, 새로운 원소를 추가하고, 이때 추가된 원소들은 기본 값을 갖게 됩니다.

void resize(size_type new_size);
void resize(size_type new_size, Type value);	// value는 늘어날 때의 기본값

 

물론, 용량도 새로운 원소를 모두 담기 위해 자동으로 늘어납니다.

반대로, 원소의 개수를 줄이면, 기존의 원소는 줄어든 만큼 삭제됩니다.

그러나, 용량을 줄이려면 메모리 재할당이 필요하므로, ( 할당된 메모리는 부분만 시스템에 반환할 수 없습니다. ) 용량은 변경되지 않습니다.

 

이와 달리, reserve는 컨테이너에 지정한 수의 원소들을 담을 수 있는 메모리를 미리 할당하는 역할을 합니다.

예를 들어, 대용량의 파일을 한 번에 읽어 들이기 위해 미리 메모리를 준비하는 상황에 사용하는 함수입니다.

void reserve(size_type count);

 

이 함수는 컨테이너의 원소 개수와는 아무런 상관이 없습니다.

그리고, 기존의 용량보다 작게 지정하면 위의 설명과 같은 이유로 용량은 변경되지 않습니다.

int main(){

    vector<int> int_vec = { 1, 2, 3, 4, 5 };
    print(int_vec);         // 이 함수는 전과 동일

    int_vec.reserve(100);   // 용량 늘림
    print(int_vec);

    int_vec.resize(100);    // 원소의 개수 늘림
    print(int_vec);
    
    int_vec.reserve(50);    // 용량을 줄일 수 없음
    print(int_vec);

    int_vec.resize(50);     // 원소의 개수 줄임
    print(int_vec);
    
    return 0;
}

▼출력

size: 5, capacity: 5

size: 5, capacity: 100

size: 100, capacity: 100

size: 100, capacity: 100

size: 50, capacity: 100

 

참고로, std::string은 내부적으로 vector <char>와 비슷합니다.

그리고, 이 string 클래스도 vector와 마찬가지로 size, resize, capacity, reserve 함수를 지원합니다.

 

이 글과 관련있는 글들

STL Vector 사용법

 

 

'C, C++ > 자료구조' 카테고리의 다른 글

[C++] STL emplace 함수 설명 및 사용법  (0) 2024.06.29
[C++] STL map 사용법  (0) 2024.06.27
[C++] 덱 ( deque ) 사용법  (0) 2024.06.12
[C++] STL list 사용법  (0) 2024.06.11
[C++] 우선 순위 큐 ( Priority Queue ) 사용법  (0) 2024.06.10
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유