C++을 쓰면서는 string만 쓰겠지 생각하지만 은근히 char*나 char 배열을 쓰는 경우가 많다(나만 그런가).
쓰다보면 저 두개의 차이점을 잘 모르겠는데 이번 기회에 공부해서 정리해보려고 한다. 그리고 string <-> char* 변환도 은근 자주 써야하는데 이거도 같이 정리해보자.
먼저 char*와 char array는 사이즈가 다르다 char*는 당연히 포인터니까 4byte이고, char array는 할당한 크기에 따라 달라질 것이다.
또 다른점은 char array는 인덱싱으로 해당 인덱스의 문자만 변경하는게 가능하다.
int main()
{
char str[10] = "Hello";
str[3] = 'r';
}
하지만 char*는 똑같이 선언해도 .rodata section에 들어가는 녀석이라서 저런식으로 수정이 불가능하다.
int main()
{
char* str = "Hello";
str[3] = 'r'; // Not allowed!
}
메모리 레이아웃중에 Data영역중에 .rodata section에는 상수 키워드로 정의된 문자열이나 printf의 format string이 들어간다(.data 영역에는 초기화된 전역변수, bss에는 초기화되지 않은 전역변수나 static 변수가 들어간다). rodata는 말그대로 read-only data이며 여기 할당됐으므로 당연히 수정이 안된다.
다음으로 string과 char* 상호간에 변환하는 방법들을 알아보자
char* -> string
int main()
{
char* ch = "Hello";
std::string str(ch);
return 0;
}
string -> char*
int main()
{
string str = "hello";
const char* ch = str.c_str();
return 0;
}
하지만 c_str()을 이용하면 const char*로 받아야 하기 때문에 수정이 불가능하다. 수정이 가능한 char*로 받으려면
int main()
{
string str = "hello";
char* ch = new char[str.length() + 1];
ch[str.length()] = '\0';
copy(str.begin(), str.end(), ch);
cout << ch << endl;
delete ch;
return 0;
}
이렇게 하면 된다(오류 C4996 'std::copy::_Unchecked_iterators::_Deprecate': Call to 'std::copy' with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' 이런 오류가 뜰 수 있는데, copy 함수가 보안상 취약하다고 판단해서 warning을 띄우는데 위 예시에서는 보안상 크게 문제될게 없으니 맨 윗줄에 #define _SCL_SECURE_NO_WARNINGS 선언해주면 warning이 없어진다),
Reference:
https://zoningout.tistory.com/112
https://kwonkyo.tistory.com/285
'공부 > C || C++' 카테고리의 다른 글
C+ 11 스마트 포인터(unique_ptr, shared_ptr, weak_ptr) (0) | 2021.07.07 |
---|---|
C++ 오버로딩(overloading) vs 오버라이딩(overriding), 가상함수(virtual function) 그리고 다형성(polymorphism) (0) | 2021.07.05 |
복사생성자란(copy constructor)? (0) | 2021.07.05 |
C++11 가변 인자 함수 템플릿(variadic template) (0) | 2021.07.04 |
C++ 11 - Rvalue reference (0) | 2021.07.03 |