📘 TIL (Today I Learned)

📌 주제

C++ 인벤토리 · 장비 시스템 구현 중 발생한 오류 분석과 해결


🧠 오늘 한 일 요약

  • 인벤토리에서 장비 아이템을 선택해 장착하는 기능 구현
  • EquipID, ItemType, Slot, Inventory 구조를 실제 로직에 연결
  • 장착 / 해제 과정에서 발생한 컴파일 오류, 런타임 오류 집중 디버깅
  • STL(vector, map) 사용 시 발생하는 대표적인 실수들 학습

❌ 문제 상황

  1. enum class 타입 오류
    • EquipID를 int로 받는 함수에 그대로 전달해서 컴파일 에러 발생
    • enum class는 암시적 형 변환이 불가능하다는 점을 간과함
  2. 초기화되지 않은 포인터 사용
    • Inventory* inv; 선언 후 바로 사용 → C6001 경고 발생
    • 포인터는 선언만으로는 객체를 가리키지 않는다는 점을 다시 확인
  3. 장착 중 인벤토리 수정으로 인한 크래시
    • 장비 장착 과정에서 inv->AddItem()을 호출
    • 인벤토리 슬롯을 순회하는 도중 컨테이너를 수정해
      vector subscript out of range, access violation 발생
  4. 초기화되지 않은 지역 변수 사용
    • EquipID oldEquip;를 선언만 하고 조건 없이 사용
    • 일부 경로에서 값이 대입되지 않아 UB(정의되지 않은 동작) 가능성 발생
  5. STL 내부 operator<에서 발생한 예외
    • 잘못된 EquipID 값이 map의 key로 사용되며 비교 중 크래시 발생
    • operator<는 정렬 기준이므로, key 값의 안정성이 매우 중요함을 체감

✅ 해결 방법

  1. 타입 일치
    • AddItem 함수의 파라미터 타입을 int가 아닌 EquipID로 수정
    • 불필요한 캐스팅 제거
  2. 포인터 안전하게 초기화
Inventory* inv = player->GetInventory();

 

   3. 장착 로직 재설계

  • 장착 = 추가(Add)가 아니라 이동(Move) 개념으로 처리
  • 새 장비는 인벤토리에 다시 넣지 않음
  • 기존 장비만 인벤토리로 반환

    4. 지역 변수 초기화 

EquipID oldEquip = EquipID::None;

 

    5. STL 컨테이너 사용 시 주의

  • 순회 중(for, range-for) 컨테이너 구조 변경 금지
  • vector 인덱스 접근 시 범위 검증 필수
  • 디버그 중에는 [] 대신 at() 사용 고려

📚 오늘 배운 점 (핵심 정리)

  • enum class는 안전하지만, 타입 설계를 처음부터 맞추지 않으면 오히려 오류가 커진다.
  • 포인터는 선언 ≠ 초기화라는 점을 항상 의식해야 한다.
  • 인벤토리와 장비 시스템은 “추가”가 아니라 소유권 이동 관점으로 설계해야 한다.
  • STL 오류의 대부분은 내 코드의 인덱스 / 생명주기 문제다.
  • 컴파일러 경고(C6001, 초기화 경고)는 무시하면 반드시 런타임에서 터진다.

🔍 느낀 점

오늘은 단순히 에러를 고치는 게 아니라,
왜 이런 구조에서는 반드시 터지는지를 이해한 하루였다.
특히 인벤토리·장비 시스템에서 컨테이너를 다루는 방식과
enum class, 포인터, STL의 관계가 명확해졌다.
디버깅 경험이 쌓이면서 코드 구조를 먼저 고민하는 습관이 중요하다는 걸 느꼈다.

'TIL' 카테고리의 다른 글

26.01.13_TIL  (0) 2026.01.13
Team7_KPT회고록  (0) 2026.01.07
26.01.05_TIL  (0) 2026.01.05
26.01.02_TIL  (0) 2026.01.02
25.12.31_TIL  (0) 2025.12.31