학습일지/C와 C++

C++ Vector

Tsukino Ren 2026. 3. 14. 22:53

Vector

Vector 란?

C++에서 vector 는 가변 크기 배열을 다루기 위한 표준 라이브러리 컨테이너다.

쉽게 말하면 배열처럼 index로 접근할 수 있는데 크기가 자동으로 늘어나는 자료구조 라고 보면 된다.

Standard Template Library (STL) [ C++표준 라이브러리 ]

메모리 자동 관리가 제공되는 자료구조 라이브러리다. 템플릿 프로그래밍 기반이라, 다양한 자료형의 데이터들을 저장 할 수 있다.

STL 자료구조에는 Vector, Map, Set, Stack, Queue, List 등이 존재한다. STL 자료구조는 컨테이너 라고도 불린다.


vector 를 왜 쓰는가?

vector 를 쓰는 가장 큰 이유는 배열보다 훨씬 유연하기에 쓰인다.

일반 배열

int arr[5] = { 1, 2, 3, 4, 5 };;
  • 이렇게 사용하며 크기가 초기화값 으로 고정된다.
  • 나중에 크기가 더 필요해도 추가가 불가능 하다.

vector

 

  • 크기를 자동으로 조절해준다
  • 배열처럼 index 접근이 가능하다
  • 데이터 추가 및 삭제가 가능하다
  • 메모리를 자동으로 관리한다

이 처럼 개발자가 메모리 크기를 일일이 신경 쓰지 않고도 배열처럼 데이터를 다룰 수 있게 해준다.


vector 를 사용하려면?

vector 는 표준 라이브러리에 들어 있으므로 헤더를 포함해야 한다.

#include <vector>

그리고 선언할때는

vector<int> v;

 

설명하자면,

  • vector 를 클래스
  • <int> 를 자료형
  • v 를 변수명

클래스<자료형> 변수명이며, 정수들을 저장하는 동적 배열을 만든것이다

 

초기값을 넣어 만들수도 있다.

vector<int> v = {10, 20, 30};

 

크기를 정해서 만들기도 가능하다

vector<int> v(5);

 

크기와 초기값을 함께 지정 할 수 있다.

vector<int> v(5, 100);

 

push_back() 함수

vector 의 맨 뒤에 요소를 추가해준다.

예시

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v;

    v.push_back(10);
    v.push_back(20);
    v.push_back(30);

    std::cout << v[0] << std::endl; // 10
    std::cout << v[1] << std::endl; // 20
    std::cout << v[2] << std::endl; // 30
}

출력


pop_back() 함수

vector 의 맨 뒤에 있는 요소를 제거한다.

허나 비어 있는 vector 에 pop_back() 함수를 호출하면 오류가 발생할 수 있다.

예시

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v;

    v.push_back(10);
   

    std::cout << v[0] << std::endl; // 10

    v.pop_back();

    std::cout << v[0] << std::endl; // 10?? 
}

출력

실행은 되나 처음 넣었고 출력한 10만 출력이 되고 뒤에 사라진 이후 출력값에서 오류가 발생한다.


size와 capacity

vector 에는 size() 와 capacity() 라는 개념이 있다.

size ()

 

현재 실제로 들어 있는 요소 개수를 뜻한다

예시

int main()
{
    std::vector<int> v(10, 1);

    std::cout << v.size() << std::endl;

    v.pop_back();
    
    std::cout << v.size() << std::endl;
}

출력

capacity()

현재 확보해둔 저장 공간의 크기를 뜻한다

예시

int main()
{
    std::vector<int> v(10, 1);

    std::cout << "\n내부 :" << v.size() << std::endl;
    std::cout << "총 크기: " << v.capacity() << std::endl;

    v.pop_back();
    
    std::cout << "\n내부 :" << v.size() << std::endl;
    std::cout << "총 크기: " << v.capacity() << std::endl;

    v.push_back(10);
    v.push_back(10);

    std::cout << "\n내부 :" << v.size() << std::endl;
    std::cout << "총 크기: " << v.capacity() << std::endl;
}

출력

여기서 보면 내부 값이 초기 총 크기값 10을 초과하니 재할당을 하여 자동으로 크기를 조절해준다.

재할당을 자주하게 되면 메모리가 연속적으로 배치되어 성능 저하가 일어나게된다.

증가 값은 컴파일 마다 다르며 필자가 사용하는 Visual Studio 는 1.5배 증가시켜준다.


clear()

모든 요소를 제거한다

예시

int main()
{
    std::vector<int> v(10, 1);

    std::cout << "\n내부 :" << v.size() << std::endl;
    std::cout << "총 크기: " << v.capacity() << std::endl;

    v.clear();

    std::cout << "\n내부 :" << v.size() << std::endl;
    std::cout << "총 크기: " << v.capacity() << std::endl;
}

출력

내부의 있는 요소들은 모두 사라진다.


empty()

비어 있으면 true 아니면 false 를 반환한다.

예시

int main()
{
    std::vector<int> v;

    if (v.empty())
    {
        std::cout << "공 백" << std::endl;
    }
}

출력


front(), back()

내부에 있는 첫 번째 요소와 마지막 요소에 접근한다.

예시

int main()
{
    std::vector<int> v = { 10, 20, 30, 40, 50 };

    std::cout << "\n첫 번째 :" << v.front() << std::endl;
    std::cout << "마지막: " << v.back() << std::endl;
}

출력

front(), back(), pop_back() 은 빈 상태에서 호출하게 되면 문제가 생기기에 empty()를 사용하여 비어있는지 확인해주고 사용하는게 좋다. 


at()

v[i] 처럼 특정 위치의 요소에 접근할 때 사용하지만 자동 범위 검사를 수행하여 안전하게 사용 할 수 있다.

예시

int main()
{
    std::vector<int> v = { 10, 20, 30, 40, 50 };

    std::cout << "\n두 번째: " << v.at(1) << std::endl;
}

출력

필자 처럼 입문중인 사람들이 디버깅 할 때는 at()이 더 안전한 것 같다.


erase()

해당 멤버 함수는 중간 원소를 지울 때 사용한다.

예시

int main()
{
    std::vector<int> v = { 10, 20, 30, 40, 50, 60 };

    for (int i = 0; i < v.size(); ++i)
    {
        std::cout << v[i] << " ";
    }

    v.erase(v.begin() + 1);
    std::cout << std::endl;

    for (int i = 0; i < v.size(); ++i)
    {
        std::cout << v[i] << " ";
    }

    v.erase(v.begin() + 1, v.begin() + 3);
    
    std::cout << std::endl;

    for (int i = 0; i < v.size(); ++i)
    {
        std::cout << v[i] << " ";
    }
}

출력

여기서 중요한 점이 있다.

erase(시작, 끝) 에서 시작은 포함을 하고 끝은 포함하지 않는다.
요소를 지우면 뒤에 있던 요소들이 앞으로 당겨지며 기존 인덱스의 기준 또한 바뀐다.

 


insert()

원하는 위치에 값을 넣을 수 있다.

예시

int main()
{
    std::vector<int> v = { 10, 20, 30 };

    v.insert(v.begin() + 1, 11);
    v.insert(v.begin() + 3, 22);

    for (int i = 0; i < v.size(); ++i)
    {
        std::cout << v[i] << " ";
    }
}

출력

index 1 의 위치에는 11이 들어가고 index 3 의 위치에는 22가 들어가는 것을 볼 수 있다.


vertor 의 장점, 단점

장점

  • 크기를 자동으로 관리하여 직접 메모리 크기를 계산할 필요가 없다
  • 연속된 메모리를 쓰기 때문에 인덱스 접근이 빨라 배열처럼 빠르게 접근이 가능하다.
  • 함수가 많아서 사용하기 편하다

단점

  • 중간 삽입 및 삭제가 느릴 수 있다
  • 재할당이 일어나면 그만큼의 비용이 든다
    공간이 부족할 때 더 큰 메모리로 옮기는 과정이 발생하며 그래서 자주 추가가 일어나는  상황에서는 성능 저하가 생긴다.

reserve()

미리 저장 공간을 확보해두는 함수다. 이게 vector 에서 초기화 값을 지정하는 거랑 비슷한듯 하나 다르다

예시

int main()
{
    std::vector<int> v(10);

    std::cout << v.size() << std::endl;
    std::cout << v.capacity() << std::endl;

    v.reserve(50);

    std::cout << v.size() << std::endl;
    std::cout << v.capacity() << std::endl;
}

출력

출력 값을 보면 바로 크기를 지정하면 10의 크기만큼 0으로 내부 값들이 채워지는 반면 reserve()를 사용하게 되면

공간만 미리 확보하는 방식이다 보니 내부 값은 비어있게 된다.이러면  push_back() 을 사용할 때 수시로 재할당을 하지 않아

성능 저하를 일으키는 일이 사라진다.


핵심 정리

  • 배열처럼 사용이 가능하고 크기가 자동으로 늘어난다.
  • 멤버 함수의 수가 많아 다양하게 사용 할 수 있다.
  • 내부족으로 연속된 메모리를 사용한다.
  • 공간 부족 시 더 큰 공간으로 재할당을 한다.

마무리

vector 는 단순히 배열을 대체하는 클래스가 아니라 데이터를 유연하고 안전하게 관리할 수 있게 해주는 핵심 컨테이너라는 것을 인지하게 되었다.

 

멤버 함수의 종류도 많고 사용 방법들도 많다보니 당장 전부 사용 할 수는 없겟다만 꾸준히 vector 를 실제로 사용해보고 익숙해 져서 다양하게 사용할 수 있도록 해야겠다.

'학습일지 > C와 C++' 카테고리의 다른 글

C++ Debugging  (0) 2026.03.16
Moderen C++  (1) 2026.03.15
C++ Template Programming  (0) 2026.03.13
C++ std::string  (0) 2026.03.13
C/C++ 상속과 다형성, 추상 클래스  (0) 2026.03.12