문자열 : c-style string vs std::string vs std::array<char, N> vs std::string_view
개요
C++에서는 문자열을 다루는 여러 가지 방법을 제공합니다. 이 문서에서는 전통적인 C-style 문자열과 모던 C++에서 권장되는 std::string
, 고정 크기 문자열을 위한 std::array<char, N>
, 그리고 C++17에 추가된 std::string_view
의 특징과 차이점을 비교 설명합니다.
C++ 버전별 주요 키워드 도입 시기
- C++98:
std::string
(Standard Template Library의 일부로 표준화) - C++11:
std::array
(고정 크기 배열 컨테이너) - C++17:
std::string_view
(문자열에 대한 소유권 없는 뷰)
내용 설명
1. C-style 문자열 (char[]
또는 char*
)
- 특징:
char
타입의 배열이며, 문자열의 끝을 알리는 null 문자(\0
)로 끝납니다. C 언어에서 유래한 가장 기본적인 형태입니다. - 장점: C 라이브러리 함수와 직접적인 호환이 가능하고, 오버헤드가 적습니다.
- 단점: 크기가 고정되어 있거나, 동적 할당 시 수동으로 메모리를 관리해야 합니다.
strcpy
,strcat
같은 함수 사용 시 버퍼 오버플로우에 취약합니다.
2. std::string
- 특징: C++ 표준 라이브러리가 제공하는 동적 문자열 클래스입니다. 문자열의 길이를 내부적으로 관리하며, 필요에 따라 자동으로 메모리를 할당하고 해제합니다.
- 장점: 메모리 관리가 자동화되어 안전하고 편리합니다.
append
,find
,substr
등 풍부한 멤버 함수를 제공하여 문자열 조작이 쉽습니다. - 단점: 동적 메모리 할당으로 인해 C-style 문자열보다 약간의 성능 오버헤드가 발생할 수 있습니다.
3. std::array<char, N>
- 특징: C++11에 도입된 고정 크기 배열 컨테이너입니다. 컴파일 시간에 크기
N
이 정해져야 합니다. - 장점: 스택에 할당되어 빠르고, STL의 다른 컨테이너처럼 반복자(
iterator
)를 사용할 수 있어 알고리즘과 함께 사용하기 편리합니다. - 단점: 크기를 동적으로 변경할 수 없습니다. null 종결을 보장하지 않으므로 C-style 함수에 전달 시 주의가 필요합니다.
4. std::string_view
(C++17)
- 특징: 문자열 데이터를 소유하지 않고, 기존 문자열의 '뷰(view)' 또는 '참조'만을 가집니다. 읽기 전용입니다.
- 장점: 문자열을 복사하지 않으므로 함수에 문자열을 전달할 때 발생하는 불필요한 메모리 할당 및 복사 비용이 없습니다.
const std::string&
보다 유연하게 다양한 문자열 타입(C-style,std::string
등)을 받을 수 있습니다. - 단점: 원본 문자열이 소멸되면
string_view
는 유효하지 않은 메모리를 가리키게 되므로(dangling pointer), 생명주기 관리에 주의해야 합니다.
예제 코드
#include <iostream>
#include <string>
#include <array>
#include <string_view>
// C++17의 std::string_view를 사용하는 함수
void print_string_view(std::string_view sv)
{
// string_view는 복사 없이 문자열을 "바라볼" 뿐입니다.
std::cout << "View: " << sv << ", Size: " << sv.size() << "\n";
}
int main()
{
// 1. C-style 문자열
char my_text1[] = "Jan"; // 컴파일러가 자동으로 null 문자를 추가 (크기 4)
char my_text2[] = {'J', 'a', 'n', '\0'}; // 명시적 null 종결
// 2. std::array<char, N>
// null 문자를 포함할 크기 4로 지정
auto my_text3 = std::array<char, 4>{"Jan"};
// 3. std::string
auto my_text4 = std::string{"Jan"};
std::cout << "std::string size: " << my_text4.size() << "\n";
my_text4.append(" Schaffranek");
std::cout << "Appended string size: " << my_text4.size() << "\n";
std::cout << "Full string: " << my_text4 << "\n\n";
// 4. std::string_view 활용
print_string_view(my_text1); // C-style string 전달
print_string_view(my_text4); // std::string 전달
print_string_view("Literal"); // 문자열 리터럴 전달
return 0;
}
실행 결과
std::string size: 3
Appended string size: 15
Full string: Jan Schaffranek
View: Jan, Size: 3
View: Jan Schaffranek, Size: 15
View: Literal, Size: 7
활용팁
std::string
: 대부분의 경우에 가장 먼저 고려해야 할 기본 문자열 타입입니다. 안전하고 기능이 풍부하여 생산성이 높습니다.C-style string
: C 라이브러리나 오래된 API와 연동해야 할 때 사용합니다.std::string
의.c_str()
멤버 함수를 통해 쉽게 변환할 수 있습니다.std::array<char, N>
: 임베디드 시스템이나 성능이 매우 중요한 환경에서, 컴파일 시간에 크기가 확정된 작은 문자열을 다룰 때 유용합니다.std::string_view
: 함수에 읽기 전용 문자열을 전달할 때 사용하면 좋습니다. 불필요한 복사를 방지하여 성능을 향상시킬 수 있습니다. 특히 문자열을 수정할 필요가 없는 함수 매개변수에const std::string&
대신 사용하는 것을 권장합니다.
'개발 > C++ (98,03,11,14,17,20,23)' 카테고리의 다른 글
Modern C++ : const reference and Value Semantics (0) | 2025.08.12 |
---|---|
Modern C++ : array vs std::array (98, 11) (1) | 2025.08.10 |
Modern C++ : anonymous namespace (98, 11, 17) (2) | 2025.08.09 |
Modern C++ : C-Style static function (98, 11) (1) | 2025.08.08 |
Modern C++ : static local variables (98, 11) (0) | 2025.08.07 |
Modern C++ : const vs constexpr (98, 11, 14, 17, 20) (0) | 2025.08.06 |
Modern C++ : type conversions (11, 14, 17, 20) (4) | 2025.08.05 |
Modern C++ : designated initializers (20) (0) | 2025.08.04 |