C ++에서 s 배열을 관리하기 위해 std::string
언제 사용해야 하며 언제 사용해야 합니까?char*
char
char*
성능 (속도)이 중요하고 메모리 관리로 인해 위험한 비즈니스를 기꺼이 받아 들일 경우 사용해야하는 것 같습니다 .
고려해야 할 다른 시나리오가 있습니까?
답변:
복사를 피하기 위해 큰 경우 참조로 std :: strings 또는 인스턴스에 대한 포인터를 전달할 수 있으므로 char 포인터를 사용하여 실제 이점을 보지 못합니다.
실제 텍스트 인 모든 것에 std :: string / wstring을 사용합니다. char *
하지만 다른 유형의 데이터에 유용하며 원하는대로 할당이 해제 될 수 있습니다. 그렇지 않으면 std :: vector가 갈 길입니다.
이 모든 것에는 예외가있을 수 있습니다.
char *
는 오버 헤드가 거의 없습니다. 정확히 어떤 오버 헤드 std::string
가 내가 알지 못하며 구현에 따라 달라질 수 있습니다. 나는 베어 char 포인터보다 오버 헤드가 훨씬 더 클 것이라고 거의 기대하지 않는다. 나는 표준 사본을 소유하고 있지 않기 때문에 표준에 의해 만들어진 어떤 보증도 자세히 설명 할 수 없습니다. 성능 차이는 수행 할 작업에 따라 달라질 수 있습니다. std::string::size
문자 데이터 옆에 크기를 저장할 수 있으므로 strlen
.
append(const string&)
및 append(const char*, size_t)
대신 operator+=()
.
내 관점은 :
예, 때로는 정말 할 수 있습니다. const char *, 스택에 할당 된 char 배열 및 문자열 리터럴을 사용할 때 메모리 할당이 전혀없는 방식으로 수행 할 수 있습니다.
이러한 코드를 작성하려면 문자열이나 벡터를 사용하는 것보다 더 많은 생각과주의가 필요하지만 적절한 기술을 사용하면 수행 할 수 있습니다. 적절한 기술을 사용하면 코드가 안전 할 수 있지만 char []로 복사 할 때 복사되는 문자열의 길이에 대한 보증이 있는지 항상 확인해야합니다. 아니면 크기가 큰 문자열을 정상적으로 확인하고 처리해야합니다. 그렇게하지 않으면 strcpy 기능 군이 안전하지 않다는 평판을 얻었습니다.
char [] 버퍼의 안전성과 관련하여 템플릿은 버퍼 크기를 처리하기위한 캡슐화를 생성 할 수 있으므로 도움이 될 수 있습니다. 이와 같은 템플릿은 Microsoft에서 strcpy를 안전하게 대체하기 위해 구현합니다. 여기 예제는 내 코드에서 추출되었으며 실제 코드에는 더 많은 메서드가 있지만 기본 아이디어를 전달하기에 충분해야합니다.
template <int Size>
class BString
{
char _data[Size];
public:
BString()
{
_data[0]=0;
// note: last character will always stay zero
// if not, overflow occurred
// all constructors should contain last element initialization
// so that it can be verified during destruction
_data[Size-1]=0;
}
const BString &operator = (const char *src)
{
strncpy(_data,src,Size-1);
return *this;
}
operator const char *() const {return _data;}
};
//! overloads that make conversion of C code easier
template <int Size>
inline const BString<Size> & strcpy(BString<Size> &dst, const char *src)
{
return dst = src;
}
char*
문자열이 항상 스택에있는 것은 아닙니다. char *str = (char*)malloc(1024); str[1024] = 0;
당신이 사용해야 하나의 기회 char*
가 아니라는 std::string
정적 문자열 상수를 필요로 할 때입니다. 그 이유는 모듈이 정적 변수를 초기화하는 순서에 대한 제어 권한이 없으며 다른 모듈의 다른 전역 개체가 초기화되기 전에 문자열을 참조 할 수 있기 때문입니다. http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Static_and_Global_Variables
std::string
장점 :
std::string
단점 :-두 개의 개별 STL 문자열 인스턴스는 동일한 기본 버퍼를 공유 할 수 없습니다. 따라서 값으로 전달하면 항상 새 사본을 얻습니다. -약간의 성능 저하가 있지만 귀하의 요구 사항이 특별하지 않으면 무시할 만하다고 말하고 싶습니다.
char*
다음과 같은 경우 에 사용하는 것을 고려해야합니다 .
실제로 C ++에서는 char*
옵션, 파일 이름 등으로 고정 된 작은 단어에 자주 사용됩니다.
C ++ std :: string을 사용하는 경우 :
char *를 사용하는 경우
라이브러리를 작성하는 경우 (const) char *를 매개 변수로 사용하십시오. std :: string 구현은 컴파일러마다 다릅니다.
std :: string (예 : 예 find
) 에 대한 대부분의 작업 은 가능한 한 최적화 될 것으로 예상 할 수 있으므로 최소한 순수한 C 대응만큼 수행 할 가능성이 높습니다.
std :: string 반복자가 기본 char 배열의 포인터에 자주 매핑된다는 점도 주목할 가치가 있습니다. 따라서 반복자 위에서 고안 한 모든 알고리즘은 성능 측면에서 char * 위에있는 동일한 알고리즘과 본질적으로 동일합니다.
주의해야 할 사항은 다음과 같습니다. operator[]
. 대부분의 STL 구현은 경계 검사를 수행하지 않으며이를 기본 문자 배열에서 동일한 작업으로 변환해야합니다. AFAIK STLPort는 선택적으로 경계 검사를 수행 할 수 있으며,이 지점에서이 연산자는 약간 느립니다.
그렇다면 std :: string을 사용하면 무엇을 얻을 수 있습니까? 수동 메모리 관리에서 벗어날 수 있습니다. 배열 크기를 조정하는 것이 더 쉬워지며 일반적으로 메모리 확보에 대해 덜 생각해야합니다.
문자열의 크기를 조정할 때 성능이 걱정된다면 reserve
유용 할 수 있는 함수가 있습니다.
성능이 중요한 경우에도 사용하는 것이 좋습니다 vector<char>
. 사전에 메모리 할당 (reserve () 메서드)을 허용하고 메모리 누수를 방지하는 데 도움이됩니다. vector :: operator []를 사용하면 오버 헤드가 발생하지만 항상 버퍼의 주소를 추출하고 char * 인 것처럼 정확히 인덱싱 할 수 있습니다.