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 사용 |
'코딩' 카테고리의 다른 글
| UE5 C++ | Actor 좌표 이동·회전 구현 (0) | 2026.03.23 |
|---|---|
| [C++] 인벤토리 시스템 구현— Project HW03 (0) | 2026.03.17 |
| [C++] 전직 & 전투 시스템 구현— Project HW02 (0) | 2026.03.11 |
| CH2 개인과제 1번 상태창 구현(2) (0) | 2026.03.05 |
| CH2 개인과제 1번 상태창 구현(1) (0) | 2026.03.04 |