C++프로그래밍/C 와 C++ 기초실습

다중 포인터 (const char**) 문자열

season97 2024. 9. 18. 19:41

※ C / C++을 이미 알고 있으나 개인적인 공부를 위해 포스팅 하는 글이므로

C++에 대한 구체적인 정보를 담고 있지 않습니다.

 


void SetMessage(const char* a)
{
	a = "Bye";
}

int main()
{
	const char* msg = "Hello";
	SetMessage(msg); //안된다.. 그대로 Hello가 출력된다
    cout << msg <<endl;
}

ㆍ 편의를 위해 스택 프레임을 텍스트로 표현해 보겠다. 앞에서부터가 높은주소다. 위코드를 해석하자면..

스택 프레임 예시

텍스트 예시 -   [매개변수] [RET] [지역변수]  [매개변수] [RET] [지역변수]

 

1)    [매개변수] [RET] [지역변수(msg(Hello주소))]  [매개변수] [RET] [지역변수]

ㆍ msg는 스택영역 지역변수로 Hello주소를 가지고있다...

 

2)    [매개변수] [RET] [지역변수 (msg(Hello주소)) ] -> [매개변수a(Hello의 주소)] [RET] [지역변수]

ㆍ SetMesege함수의 매개변수에 이 msg의 주소를 넘겨줘서 SetMesege함수는 Hello의 주소를 가지고있다

 

3)    [매개변수] [RET] [지역변수 (msg(Hello주소)) ]  [매개변수a(Bye의 주소로 변경)] [RET] [지역변수]

ㆍ 함수를 통해 a는 Hello의 주소를 가리키는게 아니라 Bye의 주소를 가리키게 된다...

 

ㆍ 즉 함수의 내용은 .rdata Bye주소[B][y][e][\0] 가 어딘가에 만들어지고 a에 넣어줘라 라는 뜻.

 

ㆍ 따라서 함수를 빠져나오며 아무 소용이 없는 함수가 되어버린다...

 


void SetMessage(const char** a)
{
	*a = "Bye";
}

int main()
{
	const char* msg = "Hello";
	const char** pp = &msg;
    	SetMessage(pp); //올바르게 Bye로 수정되어 출력됨
// 또는 SetMessage(&msg);
	cout << msg << endl;
}

 

ㆍ 원하는 결과로 출력된다. 텍스트가 Bye로 변경된다.

ㆍ 이 코드도 마찬가지로 텍스트로 된 스택프레임으로 한단계씩 살펴보자

 

스택 프레임 예시

텍스트 예시 -   [매개변수] [RET] [지역변수]  [매개변수] [RET] [지역변수]

 

1) [매개변수] [RET] [지역변수(msg(Hello주소))]  [매개변수] [RET] [지역변수]

ㆍmsg는 Hello의 주소를 들고있다.

 

2) [매개변수] [RET] [지역변수 (msg(Hello주소)) ]  [매개변수a(msg[Hello]주소)] [RET] [지역변수]

ㆍ 매개변수로 **를 받고있다. pp는 &msg를 가리키고 있다. 즉 msg의 주소를 가리키고 있다

ㆍ 그래서 msg를 한번 더 타고들어갔더니...

 

3) [매개] [RET] [지역변수]  [매개변수a(msg[Hello]를 타고들어갔더니 r.data Hello주소[H][e][l][l][o][\0] ] [RET] [지역변수]

ㆍ .rdata인 Hello주소에 접근할 수 있게 되어 그 값을 변경하는 함수를 만든것이다!

 

※ 쉽게 말로 설명해보자면

1) pp[ 주소1 ] << 8바이트(4바이트)
2) 주소1번을 타고 갔더니.....  걔도 어떤 포인터 바구니였다
3) 주소1[ 주소2 ] <<8바이트(4)
4) 주소2를 타고 갔더니... [   ] 1바이트 짜리 char바구니가 있더라

더보기

그냥 양파까기라 생각해라 const char** pp2; 순간이동을 할땐 오른쪽부터 왼쪽으로 분석해보자...

-> 오른쪽 별 하나를 없애면서 어느 바구니로 이동하는지 생각해보자
-> 또 다시 한번더 *이있으니 또 타고들어가보자 

void SetMessage2(const char*& a)
{
	a = "Bye2";
}

int main()
{
const char* msg = "Hello";
SetMessage2(msg);

cout << msg << endl;
}

ㆍ 이것도 된다 

 

ㆍ .rdata : Hello 주소[H][e][l][l][o][\0] 
ㆍ .rdata : Bye   주소[B][y][e][\0]
ㆍ  msg[ Hello주소 ]  <<  8바이트 고정크기(4바이트) 

                                  ↓

ㆍ .rdata : Hello 주소[H][e][l][l][o][\0] 
ㆍ .rdata : Bye   주소[B][y][e][\0]
ㆍ  msg[ Bye주소 ]  <<  8바이트 고정크기(4바이트) 

 

과정이 복잡하지만 결론적으로 이런 모습인것이다.

 

char* a 요놈은 배열처럼 쓸 수 있다. 첫번째 주소를 가리키기 때문

char** a 그럼 함수에 넘겨줄땐 요놈으로 해야 char*로 접근이 되는거.