언어/C&C++ 응용

[C] 이중포인터

차가운오미자 2021. 6. 14. 18:01

 

*pdata 는 data를 의미함

**ppdata 도 data를 의미함

*ppdata 는 pdata를 의미함

 

왜 이중 포인터를 사용하는가?

다음 코드를 보면..

 

void addNode(LIST* myList, MYDATA* myData) {
	
	NODE* newNode = (NODE*)malloc(sizeof(NODE));
	newNode->dataptr = myData;
	newNode->next = NULL;

	NODE* pPre = NULL;
    NODE* pLoc = NULL;
	int result = _search(myList, &pPre, &pLoc, myData);
	if (result) {
		// insert
	}
}

int _search(LIST* myList, NODE** ppPre, NODE** ppLoc, MYDATA* myDataPtr) {

	*ppPre = NULL;
	*ppLoc = myList->head;
	if (*ppLoc == NULL) {
		//the list is empty
		return 1; // put in head
	}
	else {
		while (*ppLoc != NULL) {
			int result = compareData((*ppLoc)->dataptr, myDataPtr);
			if (result == 0) {
				// data are the same; cannot put it
				printf("[_search] unable to put in data \n");
				return 0;
			}
			else if (result < 0) {
				// pLoc->data->key > myDataPtr->key => needs to go before current node
				// go to next step
				*ppPre = *ppLoc;
				*ppLoc = (*ppLoc)->next;
			}
			else {
				// pLoc->data->key < myDataPtr->key => put after pPre and before pLoc
				// calls _insert(myList, pPre, myDataPtr)
				break;
			}
		}
		return 1;
	}
}

addNode에서 _search 함수를 부르는데, 이때 addNode의 지역변수인 pPre와 pLoc에 _search 함수 내에서 적절한 노드의 주소값을 넣어줘야 한다. 여기서 이중 포인터가 아니라 단순 NODE* 를 넣어주면 아래 그림의 우상단과 같은 일이 일어난다.

// 그림 우상단의 상황
void addNode(){
    NODE* pPre;
    // 생략
    _search(... , pPre, ...){...}
}

 

 

 

즉, 우상단과 같이 매개변수로 NODE* pPre를 넘겨주면 _search 함수를 부를 때, pPre 안의 값만 넘어간다. 즉 0x10만 넘어가서 이 주소값만을 사용할 수 있게 되는 것이다. _search 에서 addNode함수 내의 지역변수인 pPre에 접근하고 싶으면 pPre의 값을 넘겨받는 것이 아니라 pPre의 주소값, 즉 &pPre를 받아야 한다.

 

예를 들어, pPre의 메모리 주소가 0x30이라면 NODE* 타입인 pPre의 주소값이 0x30인 것이고 이를 저장할 수 있는 변수는 NODE** 타입이다.

NODE** ppPre = &pPre // ppPre의 값은 0x30

 

_search()를 호출할 때 NODE** 포인터를 넘겨주어면 ppPre = 0x30이므로, 이 주소값을 이용해 바로 addNode에 있는 pPre 변수 공간에 접근할 수 있다.

*ppPre = 0x20

이렇게 해주면 pPre에 담긴 값이 0x10에서 0x20으로 바뀔 수 있다.

 

결론:

함수 호출시, 호출한 함수의 변수에 호출된 함수가 접근하기 위해서 이중 포인터가 유용하게 사용될 수 있다.

 

'언어 > C&C++ 응용' 카테고리의 다른 글

[C++] String 라이브러리  (0) 2021.06.14
[TS] Invalid address specified to RTlValidateHeap & DLL개념  (0) 2021.06.14
[TS] strcpy, strcpy_s  (0) 2021.06.14
[C] include, include guard(#idndef)  (0) 2021.06.14
[C] 메모리 동적 할당  (0) 2021.06.14