HOME > cpp > stl

C++ STL Vector 사용 방법

By JS | 27 Oct 2019

Vector는 동적으로 길이가 변하는 배열입니다. 일정 크기의 배열을 할당하고, 배열 길이를 늘려야 할 때 내부적으로 알아서 늘어납니다. 그렇기 때문에 메모리 할당에 대해서 신경쓰지 않아도 됩니다.

다른 라이브러리처럼, Vector도 add, remove, itorators 등의 함수를 제공합니다.

Vector를 사용하는 방법을 알아보겠습니다.

push_back(), pop_back()

Vector는 Stack 처럼 맨 뒤에 아이템을 저장하거나 삭제할 수 있습니다.

  • push_back() : 맨 뒤에 아이템을 저장
  • pop_back() : 맨 뒤의 아이템을 삭제

다음 예제는 push_back()으로 아이템이 배열 뒤에 저장되고, pop_back()으로 배열의 마지막 객체가 삭제되는 것을 보여줍니다.

#include <iostream>
#include <vector>
using namespace std;

int main()
{
  // 1부터 5까지 Vector에 push, 배열의 마지막에 아이템이 추가됨
  vector<int> v1;
  for (int i = 1; i <= 5; i++)
    v1.push_back(i);

  // 모든 아이템 출력
  for (int i = 0; i < v1.size(); i++)
    cout << v1[i] << " ";

  // 마지막 아이템 삭제
  v1.pop_back();

  // 모든 아이템 출력
  cout << "\n";
  for (int i = 0; i < v1.size(); i++)
    cout << v1[i] << " ";

  return 0;
}

결과

1 2 3 4 5
1 2 3 4

탐색(iterator)

배열의 아이템을 탐색하는 방법은 여러가지 방법이 있습니다.

  • Itorator로 아이템에 접근
  • 배열과 같이 [index] 로 아이템에 접근
  • at(index) 함수로 아이템에 접근

다음은 여러가지 방법으로 벡터의 모든 아이템을 출력하는 코드입니다.

#include <iostream>
#include <vector>

using namespace std;

int main()
{
  // 1~5의 숫자를 Vector에 저장
  vector<int> v1;
  for (int i = 1; i <= 5; i++)
    v1.push_back(i);

  // Iterator로 Vector의 아이템을 출력
  // begin() : 첫번째 위치의 Iterator를 리턴
  // v1.end() : 마지막 아이템 다음 위치의 Iterator를 리턴
  for (auto i = v1.begin(); i != v1.end(); ++i)
    cout << *i << " ";

  // 반대 방향으로 아이템을 출력
  // rbegin(), rend()는 역순(reverse)의 Iterator를 리턴
  cout << "\n";
  for (auto ir = v1.rbegin(); ir != v1.rend(); ++ir)
    cout << *ir << " ";

  // 배열처럼 Vector[index] 으로 아이템 출력
  cout << "\n";
  for (int i = 0; i < v1.size(); i++)
    cout << v1[i] << " ";

  // Vector.at(index)로 아이템 출력
  cout << "\n";
  for (int i = 0; i < v1.size(); i++)
    cout << v1.at(i) << " ";

  return 0;
}

결과

1 2 3 4 5
5 4 3 2 1
1 2 3 4 5
1 2 3 4 5

insert(), erase()

특정 위치에 아이템을 추가하거나 삭제하고 싶다면 다음 함수를 사용하면 됩니다.

  • insert(position, item): position 위치에 item을 추가 (postion은 iterator 객체)
  • erase(postion) : position에 해당하는 아이템을 삭제
  • erase(postion1, position2) : postion1을 포함하고, position2 이전까지의 아이템들을 모두 삭제 (position <= 삭제할 아이템 < position2)

다음은 insert()와 erase()를 사용하는 예제입니다.

#include <iostream>
#include <vector>
using namespace std;

int main()
{
  // 1~5의 숫자를 Vector에 저장
  vector<int> v1;
  for (int i = 1; i <= 5; i++)
    v1.push_back(i);

  // 배열의 첫번째와 마지막 위치에 100을 추가
  v1.insert(v1.begin(), 100);
  v1.insert(v1.end(), 100);

  // 결과 확인
  cout << "\n";
  for (int i = 0; i < v1.size(); i++)
    cout << v1[i] << " ";

  // 배열의 첫번째와 마지막의 아이템을 삭제
  // end()가 마지막 아이템을 가리키지 않기 때문에 -1을 해야 함
  v1.erase(v1.begin());
  v1.erase(v1.end()-1);

  // 결과 확인
  cout << "\n";
  for (int i = 0; i < v1.size(); i++)
    cout << v1[i] << " ";

  // 첫번째 아이템을 포함하고, "첫번째 + 3"의 위치 이전까지의 아이템들을 삭제
  v1.erase(v1.begin(), v1.begin()+3);

  // 결과 확인
  cout << "\n";
  for (int i = 0; i < v1.size(); i++)
    cout << v1[i] << " ";

  return 0;
}

결과

100 1 2 3 4 5 100
1 2 3 4 5
4 5

헷갈리는 것은 Itorator의 end() 입니다. end()는 배열 마지막의 아이템을 가리키지 않고, 마지막의 다음 아이템을 가리킵니다. 만약 end()를 삭제하려고 하면 Exception이 발생합니다.

size(), capacity()

size()는 배열의 아이템 개수를 리턴합니다. capacity()는 현재 배열의 전체 길이를 리턴합니다.

다음 코드는 배열의 size와 capacity의 관계를 보여줍니다. Vector는 동적으로 배열의 크기를 늘려주기 때문에 아이템을 추가할 때 공간이 없다면 스스로 capacity를 늘려줍니다.

#include <iostream>
#include <vector>
using namespace std;

int main()
{
  vector<int> v1;

  // 아무것도 추가하지 않았을 때의 상태
  cout << "Size : " << v1.size() << "\n";
  cout << "Capacity : " << v1.capacity() << "\n";

  // 1~5의 숫자를 vector에 추가
  for (int i = 1; i <= 5; i++)
      v1.push_back(i);

  // 현재 상태
  cout << "Size : " << v1.size() << "\n";
  cout << "Capacity : " << v1.capacity() << "\n";

  // 현재 배열 크기보다 더 많은 아이템을 추가
  for (int i = 6; i <= 9; i++)
      v1.push_back(i);

  // 배열의 capacity가 자동으로 늘어남
  cout << "Size : " << v1.size() << "\n";
  cout << "Capacity : " << v1.capacity() << "\n";

  return 0;
}

결과

Size : 0
Capacity : 0
Size : 5
Capacity : 8
Size : 9
Capacity : 16

clear(), resize(), shrinktofit(),

이 함수들은 다음과 같은 동작을 합니다. 아이템을 비우거나, 길게 늘어난 Vector의 공간을 줄여 메모리를 절약할 수 있습니다.

  • clear(): 모든 아이템을 삭제합니다.
  • resize(index): 벡터의 사이즈를 index만큼 줄입니다.
  • shrinktofit(): capacity의 크기를 size만큼 줄어들게 합니다.
#include <iostream>
#include <vector>

using namespace std;

int main()
{
  vector<int> v1;

  // 1~10의 숫자를 vector에 저장
  for (int i = 1; i <= 10; i++)
      v1.push_back(i);

  cout << "Size : " << v1.size() << "\n";
  cout << "Capacity : " << v1.capacity() << "\n";

  // size를 4로 변경
  v1.resize(4);
  cout << "Size : " << v1.size() << "\n";
  cout << "Capacity : " << v1.capacity() << "\n";

  // 모든 아이템 출력
  for (auto i = v1.begin(); i != v1.end(); ++i)
    cout << *i << " ";
  cout << "\n";

  // 모든 아이템 삭제
  v1.clear();
  cout << "Size : " << v1.size() << "\n";
  cout << "Capacity : " << v1.capacity() << "\n";

  // capacity를 size만큼 줄어들게 만듬
  v1.shrink_to_fit();
  cout << "Size : " << v1.size() << "\n";
  cout << "Capacity : " << v1.capacity() << "\n";

  return 0;
}

결과

Size : 10
Capacity : 16
Size : 4
Capacity : 16
1 2 3 4
Size : 0
Capacity : 16
Size : 0
Capacity : 0

empty()

벡터가 비어있는지 확인할 때 사용하는 함수입니다. 벡터에 아이템이 없다면 true를 리턴하며 반대의 경우 false를 리턴합니다.

#include <iostream>
#include <vector>
using namespace std;

int main()
{
  vector<int> v1;
  for (int i = 1; i <= 10; i++)
      v1.push_back(i);

  if (v1.empty())
    cout << "Vector is empty\n";
  else
    cout << "Vector is not empty\n";

  v1.clear();

  if (v1.empty())
    cout << "Vector is empty\n";
  else
    cout << "Vector is not empty\n";

  return 0;
}

결과

Vector is not empty
Vector is empty

참고