코딩

STL Vector / 고정폭 정수형 / enum class

story98138 2026. 3. 16. 20:20

 Part 1. std::vector — 동적 배열

 
개념
데이터 개수가 늘어남에 따라 자동으로 메모리를 관리해주는 배열.
내부 데이터는 연속된 메모리 공간에 저장되며, 인덱스로 임의 접근(Random Access)이 가능하다.
메모리 해제도 내부적으로 처리해주므로 delete[]를 직접 호출할 필요가 없다.

일반 배열(int arr[10])과 달리, 크기를 런타임에 자유롭게 늘리거나 줄일 수 있다. STL의 다른 컨테이너들(Map, Set, Stack 등)도 비슷한 철학으로 설계되어 있다.

 


 

핵심 API 정리

함수 동작 주의사항
push_back(val) 맨 뒤에 요소 추가 capacity 초과 시 재할당 발생
pop_back() 맨 뒤에 요소 제거 빈 벡터에서 호출 시 런타임 오류
size() 현재 저장된 요소 수 반환  
capacity() 저장 가능한 최대 요소 수 반환 size와 다름에 주의
reserve(n) capacity를 n 이상으로 확보 값 초기화 없음. n < capacity면 무시
resize(n) size를 n으로 변경 줄이면 초과분 삭제, 늘리면 0으로 초기화
clear() 모든 요소 제거 (size->0) capacity는 유지됨

 


 

size vs capacity — CurrentHP / MaxHP 비유

비유

capacity = MaxHP (현재 할당된 메모리 공간 크기, 최대치)

size = CurrentHP (실제로 데이터가 들어있는 개수)

size가 capacity를 초과하면 더 큰 공간을 새로 할당하고 데이터를 전부 복사한다. 이 재할당 비용이 크기 때문에 처음부터 reserve()로 공간을 확보해두는 것이 좋다.

 


 

Ex080101 — push_back / pop_back / capacity / size

 

// Main.cpp

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> Scores;
    Scores.reserve(8u);       // capacity = 8, size = 0

    Scores.push_back(100);    // size = 1
    Scores.push_back(98);     // size = 2

    std::cout << "Current capacity: " << Scores.capacity() << std::endl;
    std::cout << "Current size: " << Scores.size() << std::endl;
    for (size_t i = 0; i < Scores.size(); ++i)
    {
        std::cout << "Scores[" << i << "] : " << Scores[i] << std::endl;
    }

    Scores.pop_back();       // size = 1 (capacity는 그대로 8)

    std::cout << "Current capacity: " << Scores.capacity() << std::endl;
    std::cout << "Current size: " << Scores.size() << std::endl;
    for (size_t i = 0; i < Scores.size(); ++i)
    {
        std::cout << "Scores[" << i << "] : " << Scores[i] << std::endl;
    }

    // delete[] Scores; 구문이 필요없습니다.
    // Scores는 STL Vector이므로, 내부적으로 메모리 해제도 해줍니다.

    return 0;
}
📟 출력 결과
Current capacity: 8
Current size: 2
Scores[0] : 100
Scores[1] : 98
Current capacity: 8
Current size: 1
Scores[0] : 100

pop_back() 후 capacity는 여전히 8이다. size만 1로 줄어들고, 98은 논리적으로 제거된 것이다 (실제 메모리는 해제 안 됨).

 


 

Ex080102 — reserve / resize / clear

 

// Main.cpp

#include <iostream>
#include <vector>

void PrintScores(const std::vector<int>& InScores);

int main()
{
    std::vector<int> Scores01;
    Scores01.reserve(4u);

    Scores01.push_back(100);
    Scores01.push_back(98);
    Scores01.push_back(70);
    Scores01.push_back(86);   // size = 4, capacity = 4

    PrintScores(Scores01);

    Scores01.resize(2u);      // size = 2 (초과분 70, 86 삭제)

    PrintScores(Scores01);

    Scores01.clear();         // size = 0, capacity는 유지

    PrintScores(Scores01);

    return 0;
}

void PrintScores(const std::vector<int>& InScores)
{
    std::cout << "Current capacity: " << InScores.capacity() << std::endl;
    std::cout << "Current size: " << InScores.size() << std::endl;
    for (size_t i = 0; i < InScores.size(); ++i)
    {
        std::cout << "InScores[" << i << "] : " << InScores[i] << std::endl;
    }
}

 

📟 출력 결과
Current capacity: 4
Current size: 4
InScores[0] : 100
InScores[1] : 98
InScores[2] : 70
InScores[3] : 86
Current capacity: 4
Current size: 2
InScores[0] : 100
InScores[1] : 98
Current capacity: 4
Current size: 0

 

 핵심 포인트

- resize(2) → 논리적으로 70, 86이 삭제됨. capacity는 4 유지.

- clear() → size가 0이 되지만 capacity는 여전히 4. 메모리를 반납하지 않는다.

- 반복문은 항상 size() 기준으로 돌려야 한다. capacity 기준으로 돌리면 초기화 안 된 메모리를 읽게 된다.

 

 

 


Part 2. 고정폭 정수형 / enum class

 

기존 자료형의 문제 — 크기가 환경마다 다르다

⚠️ 문제
int의 크기는 컴파일러/플랫폼마다 다를 수 있다. (보통 4바이트지만 보장 안 됨)
멀티플랫폼, 네트워크 통신, 파일 입출력 등에서 크기 불일치가 버그를 유발한다.

 


 

고정폭 정수형 (Fixed-width Integer Types)

 

자료형 크기 부호 범위
int8_t 1바이트 부호 있음  -128 ~127
uint _t 1바이트 부호 없음  0 ~ 255
int16 _t 2바이트 부호 있음 -32,768 ~ 32,767
int32 _t 4바이트 부호 있음 약 +-21억
int64 _t 8바이트 부호 있음  매우 큰 범위

 


 

기존 enum의 문제점

⚠️ 문제
서로 다른 enum끼리 비교해도 컴파일 에러가 안 난다.
enum 값을 int에 암시적으로 대입할 수 있어 의도치 않은 사용이 가능하다.

 

enum EPosition { TOP, JUNGLE, MID, SUPPORT, BOTTOM };
enum EChamp    { LEESIN, LULU, ZED, BLITZ, MISSFORTUNE };

int main()
{
    EPosition MyPosition = SUPPORT;
    EChamp    MyChamp    = BLITZ;

    int Number = MyPosition;        // 컴파일 OK — 근데 이게 맞나?
    if (MyPosition == ZED)          // 컴파일 OK — 완전히 다른 enum인데!
    { }

    return 0;
}

 


enum class — 독자적 자료형으로 격상

 

개념
C++11부터 지원. 다른 enum class나 int로의 암시적 캐스팅이 완전히 차단된다.
필요하면 static_cast<int>()로 명시적으로 변환해야 한다.
멤버 접근은 EPosition::TOP처럼 범위 지정 연산자를 써야 한다.

 

 


Ex090102 — enum class 컴파일 에러 예시

 

enum class EPosition { TOP, JUNGLE, MID, SUPPORT, BOTTOM };
enum class EChamp    { LEESIN, LULU, ZED, BLITZ, MISSFORTUNE };

int main()
{
    EPosition MyPosition = EPosition::SUPPORT;
    EChamp    MyChamp    = EChamp::BLITZ;

    int Number = MyPosition;            // ❌ 컴파일 에러 — 암시적 변환 불가
    if (MyPosition == EChamp::ZED) {}   // ❌ 컴파일 에러 — 다른 enum class 비교 불가

    // ✅ 루프에서 쓰려면 명시적 캐스팅 필요
    for (int i = static_cast<int>(EPosition::TOP);
              i <= static_cast<int>(EPosition::BOTTOM); ++i)
    {
    }

    return 0;
}

 


 

Ex090103 — enum class에 바이트 크기 지정 + Pixel 클래스

 

// Pixel.h

#pragma once
#include <cstdint>

enum class EColor : uint8_t   // 1바이트로 크기 제한
{
    Red,
    Green,
    Blue,
};

class Pixel
{
public:
    Pixel(const EColor InColor) : Color(InColor) {}
    ~Pixel() {}

    inline EColor GetColor() const { return Color; }
    void PrintColor() const;

private:
    EColor Color;
};

 

// Pixel.cpp

#include "Pixel.h"
#include <iostream>

void Pixel::PrintColor() const
{
    switch (Color)
    {
    case EColor::Red:   std::cout << "RED"   << std::endl; break;
    case EColor::Green: std::cout << "GREEN" << std::endl; break;
    case EColor::Blue:  std::cout << "BLUE"  << std::endl; break;
    default:            std::cout << "INVALID" << std::endl; break;
    }
}

 

// Main.cpp

#include "Pixel.h"

int main()
{
    Pixel Pixel01(EColor::Red);
    Pixel Pixel02(EColor::Blue);
    Pixel Pixel03(EColor::Green);

    Pixel01.PrintColor();   // RED
    Pixel02.PrintColor();   // BLUE
    Pixel03.PrintColor();   // GREEN

    return 0;
}

 

 핵심 포인트

- enum class EColor : uint8_t — EColor 하나를 저장하는 데 1바이트만 사용한다. Pixel 수천 개를 다루는 상황에서 메모리 절약에 유리하다.


- switch문으로 enum class를 분기할 때는 반드시 EColor::Red 형태로 써야 한다.

 


오늘의 정리

vector 동적 배열. 메모리 자동 관리, 연속 메모리, 랜덤 접근 가능
reserve() capacity(통 크기)만 확보. 초기화 없음. 재할당 비용 방지용
resize() size(물의 양) 조정. 줄이면 삭제, 늘리면 0으로 초기화
clear() size → 0. capacity 유지
capacity 자동 증가 초과 시 약 1.5배 재할당 + 전체 복사 발생 → 미리 reserve() 권장
STL 대체품 UE5는 TArray/TMap. 개념은 동일해서 STL 익히면 자연스럽게 따라온다
고정폭 정수형 int8_t, uint32_t 등 — 플랫폼 무관하게 크기 보장. 가독성도 향상
enum class 암시적 캐스팅 차단, 타입 안전성 보장. 앞으로는 enum 대신 enum class 사용