숏컷 코드
#include <vector>
#include <string>
std::vector<int> v{1, 2, 3};
v.push_back(4);
v.reserve(100); // 재할당 방지
std::string s = "Hello";
s += ", World";
std::cout << s.size() << " " << s.substr(0, 5); // 12 Hello작고 연속적인 값 묶음이면 vector, 가변 텍스트면 string부터 시작하면 됩니다. 둘 다 연속 메모리 기반이라 인덱싱은 빠르지만, 재할당과 경계는 같이 봐야 합니다.
문법
이 카드에서 먼저 다시 보는 기본형은 아래입니다.
vector생성과push_backreserve와size/capacitystring연결과 부분 문자열- 인덱스 접근과
at()
어떤 기본 컨테이너를 먼저 고르면 되나
| 상황 | 먼저 떠올릴 것 |
|---|---|
| 가변 길이 값 묶음 | std::vector |
| 가변 텍스트 | std::string |
| 삽입 수를 대략 안다 | reserve() |
| 경계 검사까지 필요 | at() |
| 객체를 바로 만들며 넣기 | emplace_back() |
std::vector<int> numbers{1, 2, 3};
numbers.push_back(4);
std::string name = "Ref";
name += "Dock";vector는 커지면서 재할당할 수 있다
vector는 내부적으로 연속 배열을 유지합니다. 꽉 차면 더 큰 메모리를 새로 할당하고 원소를 모두 이동(move)합니다. 크기를 2배씩 늘리는 전략으로 push_back의 분할 상환 비용은 O(1)입니다. 하지만 재할당이 일어나면 기존 원소를 가리키던 모든 반복자와 포인터가 무효화됩니다.
std::vector<int> v;
// 삽입 전에 크기를 알면 reserve — 재할당 없음
v.reserve(1000);
for (int i = 0; i < 1000; ++i) v.push_back(i); // 재할당 0회
// 주의: reserve 후에도 size()는 0
std::cout << v.size(); // 0 (아직 비어 있음)
std::cout << v.capacity(); // 1000 (메모리만 확보)push_back은 기존 객체를 벡터에 복사하거나 이동합니다. emplace_back은 인자를 전달받아 벡터 내부에서 직접 객체를 생성하므로 임시 객체 생성이 없습니다.
std::vector<std::pair<int, std::string>> v;
v.push_back({1, "one"}); // pair 임시 생성 후 이동
v.emplace_back(1, "one"); // 벡터 안에서 pair 직접 생성 (효율적)
v.emplace_back(std::make_pair(1, "one")); // 이것도 가능하지만 중간 단계 있음// ❌ reserve만 해두고 원소가 생겼다고 착각
std::vector<int> values;
values.reserve(10);
// values[0] = 1;
// ✅ 원소를 실제로 만들려면 push_back / resize
values.push_back(1);
values.resize(10);대부분의 표준 라이브러리 구현은 짧은 문자열(15자 이하)을 힙 할당 없이 객체 안에 직접 저장합니다(SSO, Small String Optimization). 따라서 짧은 문자열 연산은 매우 빠릅니다.
std::string s = "Hello, World!";
// 기본 조작
s.size(); // 13 (바이트 수)
s.empty(); // false
s += "!"; // 이어 붙이기
s.substr(0, 5); // "Hello"
s.find("World"); // 7 (없으면 string::npos)
s[0]; // 'H'
// 변환
int n = std::stoi("42"); // 문자열 → 정수
std::string str = std::to_string(42); // 정수 → 문자열선택 기준
- 원소 수를 모으는 기본 컨테이너:
vector - 가변 텍스트:
string - 삽입 전 크기를 대략 알면
reserve - 이미 만든 객체를 넣으면
push_back - 인자로 바로 만들면
emplace_back - 경계 검사까지 원하면
at()
주의할 점
vector에 원소를 추가하면 재할당이 일어날 수 있고 기존 반복자·포인터·참조가 무효화됩니다.
std::vector<int> v{1, 2, 3};
int* ptr = &v[0]; // v[0]의 주소
v.push_back(4); // 재할당 발생 가능
std::cout << *ptr; // ❌ ptr이 이미 해제된 메모리를 가리킬 수 있음
// ✅ 재할당 없도록 미리 reserve
v.reserve(10);
int* ptr2 = &v[0];
v.push_back(4); // capacity 안에서 — ptr2 여전히 유효// ❌ reserve는 메모리만 확보하고 원소를 만들지 않는다
std::vector<int> values;
values.reserve(10);
values[0] = 1; // 잘못된 접근
// ✅ 원소를 실제로 만들려면 push_back 또는 resize
values.push_back(1);참고 링크
2 sources