Side Project/C++ 관련

[C++] std::vector의 reserve와 resize

developer-yesming 2024. 8. 2. 23:36
반응형

0. 들어가며

대부분의 C++ 개발자들은 알고있는 사실일 수 있으나, 정리차원에서 간단하게 reserve와 resize의 차이, 그리고 사용 결과에 대해서 알아보려고 한다.

vector 형의 단점

vector는 값을 집어넣는 것도 빠르고emplace_back(), 중간 값을 찾는 것도 빠르며 vector[idx], 기본적으로 여러 라이브러리에서 지원하는 기능이 많아서 사용하기에 편리하지만,(max_element 등) 단점도 있다.

  1. vector의 앞쪽으로 값을 넣으면, 시간이 오래걸린다. 이는 넣은 위치에서 뒤쪽에 있는 값들은 모두 한칸식 밀려나기 때문이다. 뒤에 넣는 것은 상관없다.
  2. vector의 용량 이상의 값을 추가할 때, vector를 확장하는 것에 시간이 소요된다.

여기서는 2번 문제와 관련된 해결책을 살펴볼 것이다.

함수

1. reserve()

이 함수는 vector의 용량을 늘릴 때 사용한다.
용량을 충분히 (넣을 vector 요소의 갯수보다 크게) 확보해 두면, 불필요하게 vector의 확장에 소요되는 시간이 없어진다.
다만, 이는 용량만 확장했으므로, .size()를 실행했을 때는 0으로 나온다.

#include <stdio.h>

#include <vector>

using namespace std;
int main() {
  vector<int> vec;
  vec.reserve(100);

  printf("capacity: %d\n", vec.capacity());
  printf("size: %d\n", vec.size());
  return 0;
}

Result:

  • capacity: 100
  • size: 0

재밌는 사실

reserve(100)를 하면, 값이 지정되지는 않았으니, cout << vec[105]를 하면 에러가 나오거나, 값이 안나와야 한다고 생각할 수 있지만...
실제로 테스트해보면, 에러는 발생할 수도 있고 아닐 수도 있고, 쓰레기 값을 뱉을 수도 있고, 0을 뱉을 수도 있다. (그래서 위험하다. 차라리 항상 죽어버리면 빠르게 고치기라도 하지...)

테스트 코드는 아래와 같다.

int i = 0;
while (i < 50000) {
  ++i;
  if (vec[i] != 0) {
    cout << vec[i] << " i: " << i << "\n";
  }
}  

Result:

  • 1041 i: 102
  • 825503793 i: 104
  • 959918896 i: 105
  • 979968054 i: 106
  • 909127968 i: 107
  • 10 i: 108
  • 60337 i: 362
  • Segmentation fault (core dumped)
    결국에는 죽었다.

2. resize()

이 함수를 사용하면, vector의 크기만 늘어날 뿐 아니라 (capacity는 당연히 증가하고), 값도 지정할 수 있다 .resize(size, initial_number). initial_number를 지정하지 않은 경우, 기본값은 0 이다.
Ex) vec.resize(10, 1); // 1로 초기화

#include <stdio.h>

#include <vector>

using namespace std;
int main() {
  vector<int> vec;
  vec.resize(100);

  printf("capacity: %d\n", vec.capacity());
  printf("size: %d\n", vec.size());
  return 0;
}

Result:

  • capacity: 100
  • size: 100

추가 사실

resize()는 초기화를 시킨다고 했지만, 값이 지정되지 않은 요소만 건드린다.
예를 들어, 아래와 같은 코드가 있을 때,

vector<int> vec;
vec.resize(2);
vec[0] = 0;
vec[1] = 1;
vec.resize(5, 3);

최종적으로 vec에 들어 있는 값은 [0, 1, 3, 3, 3]이다.
그럼 전체를 모두 초기화 하려면 어떻게 해야하냐?
.clear()함수를 사용한 이후 .resize(5,3)을 하면 된다.

반응형