본문으로 건너뛰기
모던 C++ 심화LESSON 14

std::vector: 동적 배열, 재할당, iterator 무효화

난이도중급 → 심화
예상 시간70분
선수지식이전 강의

14강. std::vector: 동적 배열, 재할당, iterator 무효화

이번 강의에서 해결할 문제​

vector 원소의 주소를 저장한 뒤 push_back을 호출하면 capacity가 부족할 때 새 저장소로 원소가 이동합니다. 예전 주소가 우연히 값을 보여도 역참조는 UB입니다. 컨테이너를 쓰는 것과 그 관찰자 수명을 설계하는 일은 함께 가야 합니다.

학습 목표​

먼저 알아야 할 핵심 개념​

vector는 원소를 연속 저장합니다. size는 실제 원소 수, capacity는 재할당 없이 보관 가능한 수입니다. capacity를 넘는 삽입은 새 연속 저장소를 할당하고 원소를 이동·복사한 뒤 기존 저장소를 정리할 수 있습니다. 이때 모든 기존 포인터·참조·iterator가 무효화됩니다.

왜 이 문제가 위험한가​

무효화된 주소는 null로 바뀌지 않습니다. 디버거에서 이전 값이 보여도 더는 유효한 객체가 아닙니다. reserve는 예상 재할당을 줄일 뿐 영구 주소 안정성을 보장하지 않으며, erase는 지점 이후 원소를 이동시킬 수 있습니다.

가장 작은 예제로 시작하기​

vector_reallocation.cpp
#include <iostream>
#include <string>
#include <vector>

struct Task { int id{}; std::string name; };

Task* findById(std::vector<Task>& tasks, int id) {
for (Task& task : tasks) {
if (task.id == id) return &task;
}
return nullptr;
}

int main() {
std::vector<Task> tasks;
tasks.reserve(2);
tasks.push_back({1, "build"});
tasks.push_back({2, "test"});

const int selectedId = 1;
tasks.push_back({3, "package"});
if (Task* selected = findById(tasks, selectedId)) {
std::cout << selected->name << '\n';
}
}

코드 한 줄씩 이해하기​

  1. reserve(2)는 두 원소까지 재할당을 피하도록 용량을 요청합니다.
  2. 세 번째 삽입은 capacity 증가를 유발할 수 있으므로 이전 주소를 사용하지 않습니다.
  3. 선택 상태는 Task*가 아니라 안정된 정수 ID로 보관합니다.
  4. 컨테이너 변경 뒤 findById로 현재 원소 주소를 다시 얻습니다.
  5. 조회 결과가 없을 수 있으므로 포인터 null을 검사합니다.

실행 결과와 메모리·동작 흐름​

출력은 build입니다. 세 번째 삽입 전후 tasks.data() 주소는 달라질 수 있습니다. 프로그램은 이전 주소에 의존하지 않고 ID로 다시 찾기 때문에 재할당 여부와 관계없이 올바른 현재 객체를 사용합니다.

단계별 실습​

흔한 실수와 해결 방법​

언제 사용하고 언제 피할까​

순차 순회가 많고 연속 저장이 유리한 기본 동적 배열로 vector를 우선합니다. 중간 삽입이 매우 많거나 원소 주소 안정성이 필수라면 요구사항을 재검토하고 다른 컨테이너 또는 간접 소유 구조를 측정해 선택합니다.

게임 개발 연결​

Unreal의 TArray도 연속 저장과 재할당 개념이 있어 원소 포인터·참조를 장기 보관하면 위험할 수 있습니다. 정확한 무효화 규칙은 엔진 버전 API 문서를 확인하고, UObject 수명은 TArray 보관 여부와 별도로 GC 규칙을 따릅니다.

이해 점검 질문 3개​

  1. vector 재할당이 기존 원소 포인터를 무효화하는 이유는 무엇인가요?
  2. reserve가 무효화를 완전히 막지 못하는 이유는 무엇인가요?
  3. 장기 선택 상태에 주소보다 ID가 유리한 경우는 언제인가요?

핵심 요약​

다음 강의 연결​

15강. 연관 컨테이너 선택에서 키 조회, 정렬 순서와 해시 비용을 비교합니다.

MINI QUIZ

std::vector: 동적 배열, 재할당, iterator 무효화 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1다음 중 “std::vector: 동적 배열, 재할당, iterator 무효화”의 핵심 요약을 실제 상황에 맞게 적용한 것은 무엇인가요?
  2. 문제 2“std::vector: 동적 배열, 재할당, iterator 무효화” 실습 중 ‘reserve가 주소를 영원히 고정한다고 생각’ 상황을 발견했습니다. 본문과 일치하는 설명은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

14강. std::vector: 동적 배열, 재할당, iterator 무효화 미완료 상태