C++ std::string_view, 문자열을 복사 없이 보는 법
**std::string_view**는 문자 시퀀스를 소유하지 않고 가리키는 C++17 뷰이며, 문자열을 복사 없이 읽을 때 씁니다.
이 글은 cppreference의 string_view 문서를 2026-08-30 기준으로 정리한 일반 설명이며, 표준 버전과 구현에 따라 세부 동작은 달라질 수 있습니다.
std::string_view는 무엇인가?
한 줄 답: 이 타입은 문자 시퀀스를 소유하지 않고 가리키는 C++17 뷰입니다.
이 타입은 <string_view> 헤더에 정의된 basic_string_view 클래스 템플릿이며, C++17부터 제공합니다. 이 이름은 char를 다루도록 특수화한 std::basic_string_view<char>의 별칭입니다.
이 뷰는 첫 원소가 위치 0에 있는 상수 연속 CharT 시퀀스를 가리킵니다. 설명용 데이터 멤버로는 기반 시퀀스를 가리키는 포인터와 문자 수가 있으며, 문자 자체를 보관하는 버퍼는 갖지 않습니다.
가리키는 대상이 상수 문자 시퀀스이므로 iterator와 const_iterator는 같은 타입이며, 이 뷰를 통해 문자를 수정하지 않습니다. span은 연속된 객체 시퀀스의 뷰이고, 이 타입은 문자 시퀀스의 뷰입니다.
std::string과 무엇이 다른가?
한 줄 답: std::string은 문자 시퀀스를 저장하고 조작하는 소유 타입이고, 이 뷰는 원본을 가리키기만 합니다.
std::string은 문자 시퀀스를 저장하고 조작하지만, 이 뷰는 기존의 상수 연속 문자 시퀀스를 가리킵니다. 따라서 이 뷰를 복사할 때는 문자 자체가 아니라 기반 시퀀스의 포인터와 문자 수 같은 범위 정보가 복사됩니다.
문자열 객체를 이 뷰로 변환하면 문자열의 data()와 size()로 만든 것과 같은 전체 범위를 나타냅니다. 이 변환은 문자열을 함수의 뷰 매개변수에 전달할 때도 사용됩니다.
이 뷰는 메모리를 소유하지 않습니다. 원본 문자열의 저장 공간과 수명은 이 타입이 대신 관리하지 않으므로, 뷰를 보관할 때는 원본이 계속 유효한지 별도로 확인해야 합니다.
함수 인자로는 어떻게 쓰나?
한 줄 답: 읽기 전용 문자열 인자를 이 뷰로 받으면 문자 버퍼를 복사하지 않고 범위를 넘깁니다.
읽기만 하는 함수는 뷰를 값으로 받는 매개변수를 사용할 수 있습니다. 다음 함수는 전달받은 범위의 size() 같은 관찰자를 함수 안에서 사용할 수 있는 형태입니다.
void show_wstring_size(std::wstring_view text) {
// text.size()
}
호출부에서 std::wstring을 이 매개변수에 전달하면 문자열의 변환 연산자를 통해 전체 문자 범위를 나타내는 뷰가 만들어집니다. 뷰를 값으로 전달하는 일은 범위 정보를 넘기는 것이며, 원본 문자를 새 버퍼에 복사하는 일은 아닙니다.
C++17에서 포인터와 문자 수를 함께 주는 형식은 지정한 개수만큼의 범위를 가리키므로 중간 널 문자도 포함할 수 있습니다. 널 종료 문자 포인터만 주는 형식은 첫 널 문자를 끝으로 처리합니다.
char text[] = {'O', 'n', 'e', '\0', 'T', 'w', 'o', '\0'};
std::string_view counted(text, 7); // 중간 널 문자 포함
std::string_view terminated(text); // 첫 널 문자에서 끝남
포인터와 문자 수로 지정하는 [s, s + count) 범위는 유효해야 합니다. C++17부터는 operator""sv 리터럴 연산자로 문자 배열 리터럴에서 뷰를 만드는 형태도 제공됩니다.
수명이 끊기면 왜 위험한가?
한 줄 답: 이 뷰는 원본 문자 배열의 수명에 의존하며, 원본이 사라지면 댕글링 뷰가 됩니다.
프로그래머는 이 뷰가 가리키는 문자 배열보다 오래 살아 있지 않도록 보장해야 합니다. 문자열 리터럴은 지속되는 저장소에 있는 정적 배열을 가리키므로 다음과 같이 뷰를 만드는 것은 안전한 예입니다.
std::string_view good{"a string literal"};
반대로 std::string 임시 객체에서 만든 뷰를 저장하면 원본이 문장 끝에 파괴될 수 있습니다. 다음 예에서는 문자열 리터럴의 s 연산자가 만든 임시 문자열이 문장 끝에 파괴되므로 뷰가 댕글링 상태가 됩니다.
using namespace std::string_literals;
std::string_view bad{"a temporary string"s};
임시 문자열을 함수 인자로 바로 넘기는 경우에는 전체 표현식이 끝날 때까지 임시 객체가 살아 있으므로 허용됩니다. 그러나 같은 임시 객체에서 뷰를 만들어 저장하면 함수 호출 뒤에도 뷰가 남아 원본을 가리킬 수 있습니다.
int x = f(get_string()); // OK
std::string_view sv = get_string(); // dangling
또한 [str.data(), str.data() + str.size()) 범위의 포인터를 무효화하는 원본 연산이 일어나면, 그 범위 원소에 대한 포인터·반복자·참조도 무효화됩니다. 따라서 뷰를 사용하기 전에는 원본 문자 배열의 수명뿐 아니라 원본을 변경한 연산으로 포인터가 무효화되지 않았는지도 확인해야 합니다.
관련 C++ 핵심 개념을 별도로 점검하려면 C++ 기술면접 질문 10가지를 참고할 수 있습니다.
FAQ
한 줄 답: C++17 지원 여부와 원본 문자열의 수명을 함께 확인하면 됩니다.
| 질문 | 답변 |
|---|---|
| C++ 몇 표준부터 쓸 수 있습니까? | C++17부터 사용할 수 있습니다. |
std::string 대신 이 타입을 쓰면 복사가 없습니까? | 이 뷰는 문자를 복사하지 않고 원본을 가리킵니다. 대신 원본 수명에 의존합니다. |
| 문자열 리터럴을 이 뷰로 보는 것은 안전합니까? | 문자열 리터럴은 지속되는 저장소에 있으므로, 이를 가리키는 것은 공식 문서의 안전한 예에 해당합니다. |
임시 std::string을 넘기면 어떻게 됩니까? | 함수 인자로 바로 쓰는 f(get_string())는 전체 표현식 동안 임시 객체가 살아 있어 허용됩니다. 임시에서 뷰를 만들어 저장하면 댕글링 포인터가 됩니다. |
출처
한 줄 답: 본문 사실과 짧은 코드 형태는 2026-08-30 기준으로 확인한 cppreference 문서만 사용합니다.
- basic_string_view — 클래스 템플릿 정의, 별칭, 관찰자, 무효화 규칙, 수명 예시를 확인했습니다.
- basic_string_view 생성자 — 빈 뷰, 포인터와 문자 수, 널 종료 문자 포인터 생성 형태를 확인했습니다.
- basic_string의 string_view 변환 — 문자열 변환과 함수 인자·임시 객체 수명 예시를 확인했습니다.