공부/C || C++

C 헷갈리는 char*와 char[] 그리고 string <-> char* 변환 방법

sudo 2021. 7. 5. 03:33

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!
}

출처: https://ffun.tistory.com/entry/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0

메모리 레이아웃중에 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

 

[C] char[] 와 char *의 차이

내가 얼마나 무지하면 어지껏 이 차이도 몰랐단 말인가. 약간의 삽질과 구글링을 통해 알아낸 내용이다. 너무도 간단하게 배열 = 포인터 라는 지식이 불러온 삽질이라 할 수 있다. 먼저 두 예제

zoningout.tistory.com

https://kwonkyo.tistory.com/285

 

문자열 상호 형변환, char* ↔ std::string ↔ CString ↔ std::stringstream

문자열간 형변환 방법입니다. 워낙 많이 쓰이기 때문에 자료가 많긴하지만 매번 찾아보는것도 귀찮아서 정리했습니다. char* ↔ std::string char* to string #include char c[256] = "Hi there"; std:string str..

kwonkyo.tistory.com