다중 포인터

CJB_ny·2022년 8월 4일
0

C++ 정리

목록 보기
39/95
post-thumbnail
const char* msg = "Hello";
// 이 녀석은 지금 .rddata영역에 들어간 녀석이다.
// 수정이 불가하다.

SetMsg(const char* a)
{
	a = "Bye";
}
// SetMSG 함수에 인자로 넘겨주어도 수정이 안된다.

const 가 안 붙어있다는 가정하에 값을 수정을 할려면

*a = "머시기"; 이런식으로 수정해야한다.

const char msg의 경우 const 가 이전에 붙어있어서

포인터 변수가 가르키는 곳의 데이터를 수정못한다!

그래서 수정이 안되는 이유?

msg의 문자열이 수정이 안되는 이유?

현재 Hello는 rodata영역에 '\n'까지 포함해서 있고

msg는 주소를 담고잇는 8바이트짜리 포인터 변수이다.

그래서Hello의 시작주소를 msg가 담고있는 것이다.

msg는 스택영역에 있는 포인터 변수이다.

스택 프레임 보기

지금 main함수의 스택은 이런식이고

SetMessage를 호출하면

Hello의 주소를 그대로 넘겨준 상황이다.

질문 ❗❗❗

문자열이 수정이 불가능 한 이유로는
rodata영역에 들어가기 때문에 수정이 불가능하고 또한 
const가 이전에 붙어있어서 주소로 접근하여 값을 수정하는 것이 불가능하다. (msg라는 포인터 변수의 데이터(가르키는 주소는 수정이 가능하다)
그리고 SetMessage함수에 msg의 주소(값을)를 const char
a로 넘겨주고
a = "Bye"; 로 선언 및 초기화를 해주었을 경우
a는 const char* a 즉, a가 가르키는 값(주소)의 값(데이터 == Hello라는 문자열)수정이 불가능 한 것이지
a라는 포인터 변수가 담고있는 값부분(주소값)을 수정하는 게 불가능 한 것이 아니다.
따라서
SetMessage 함수가 호출되면
a라는 포인터 변수에 처음에 
msg의 값에 담긴 "Hello"라는 문자열의 첫번째 주소값이 a에 담기기는 하지만,
a = "Bye"로 인해
데이터 영역에 있는 "Bye"의 첫번째 주소가 a라는 포인터 변수의 값에 할당된다.
그리고
a라는 포인터 변수는 스택메모리에 쌓인다.
SetMessage함수 호출이 종료되고 나면 a 포인터 변수 메모리 공간은 해제된다.
(함수 호출이 종료되면 사용할 수 없는 포인터 변수이다)

이중 포인터 ❗❗❗

const char** pp;

를 처음에 해석을

(const char*)* pp;

포인터 변수인데 그 해석자료형을

const char* 로 보겠다라는 의미이다.

그러면 pp는 포인터 변수라서

(편의상 4바이트)

주소값변수명들고있는 값
0x12121212ppconst char* 라고 보는 포인터 변수

지금 디버그를 보면은

ptr이라는 8바이트 포인터 변수를 보면은

주소값변수명들고있는 값
0x000000cc9b6ffb98ptr0x000000cc9b6ffb74 (num이라는 변수의 주소를 가르킴)
0x000000cc9b6ffbb8pp0x000000cc9b6ffb98 (ptr이라는 포인텨 변수의 주소를 가르킴)

즉, 이중 포인터는 값으로 포인터 변수의 주소를 가르킨다.

int num = 100;
	int* ptr = #
	int* ptr2 = nullptr;

	int** pp;

	pp = &ptr;

	**pp = 200;

	cout << **pp << endl;
	cout << num << endl;

	cout << "pp의 주소(값) 변경" << endl;
	*pp = ptr2;
	cout << *pp << endl;
	cout << **pp << endl;

지금 pp의 값을 nullptr로 변경하고나서 **pp로

값에 접근을 하게되면 에러가 난다.

이렇게 해주면 "Bye"가 뜨는것을 확인이 가능하다.

참조 ❗❗

인자로 const char*& a 이런것도 가능함.

이렇게하면

인자로 념구준 msg = "Hello" 라는 녀석을 a라는 변수명으로 참조를 하겟다 인데

다시 a의 * 로 값에 접근

즉, msg의 값부분에 접근(Hello의 H의 주소에 접근) 하여

msg = Wow로 바꾸겠다 이다.

msg의 주소값은 똑같고 값부분의 데이터가 변경이됨.

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글