size와 capacity의 차이점
vector의 멤버 함수인 size는 vector의 원소 개수를 반환하는 함수입니다.
또한, 이 함수는 모든 컨테이너의 기본 인터페이스이기도 합니다.
그렇지만, capacity는 vector 컨테이너에만 있는 독특한 함수입니다.
이 함수가 하는 일은 현재 컨테이너가 저장할 수 있는 원소의 개수를 알려주는 것입니다.
이를 통해서, vector는 원소의 개수가 늘어나는 경우에도, 잦은 메모리 재할당 횟수를 줄일 수 있습니다.
아래의 예문은 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_size는 size와 마찬가지로, 모든 컨테이너가 가진 인터페이스 함수입니다.
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 함수를 지원합니다.
이 글과 관련있는 글들
'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 |