일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- #useRef #언제 쓰는데?
- rate limit
- donwstream #upstream #origin
- 빡킹독
- raect typescript #react #typescript #styled-component
- React-Query
- 코드스테이츠 #알고리즘 #그리디
- 다익스트라 #파티 #백준
- 얕은 복사 #깊은 복사 #shallow copy #deep copy
- npm #not being able to find a file #npm install Error
- React #controlled component #비제어 컴포넌트 #제어 컴포넌트
- html entities
- react #useCallback #react Hook
- react fragment
- axios
- React #리액트 이벤트 주기 #리액트 이벤트
- React #Hook rules #Hook 규칙
- 노마드 코더 #타입스크립트 #typescript #class
- RateLimit
- 백준 #적록색약
- useState #Hooks
- DP #c++
- interceptors
- 백준 #직각삼각형
- 버블링 #갭쳐링 #이벤트 #JS
- JWT #토큰 #refreshToken #accessToken #Token #token #localStorage #sessionStorage
- React #effect hook #useEffect
- 이친수
- 플로이드 #c++
- react
- Today
- Total
꿈꾸는 개발자
C언어 이중포인터 매개변수 설명하기!(코딩도장 코드 참고) 본문
- 이중포인터 매개변수 사용하기!
#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
void allocMemory(void *ptr, int size) // 반환값 없음, void 포인터 매개변수 지정
{
ptr = malloc(size); // ptr은 allocMemory를 벗어나면 사용할 수 없음
}
int main()
{
long long *numPtr = NULL;
// numPtr과 할당할 크기를 넣어줌
allocMemory(numPtr, sizeof(long long));
*numPtr = 10; // 메모리가 할당되지 않았으므로 실행 에러
printf("%lld\n", *numPtr);
free(numPtr);
return 0;
}
해당 코드를 실행하보면 실질적으로 될 것 같지만, 에러가 발생하게 된다. 에러의 원인은 *numPtr 포인터 변수가 NULL;로 설정돼 있기 때문이다.
분명 매개변수로 지정해서, 넘겨준 것 같지만 왜 *numPtr에 동적할당된 주솟값이 저장되지 않았는지 의문이 들 수 있다.
하지만, 실제로, 매개변수는 말 그대로, 함수 내에서 자체적으로 생성되는 변수로 가정해야 한다! 따라서, 이 경우
allocMemory라는 함수가 실행되면서, 새로운 변수인 void *ptr이 스택 메모리에 생성됨을 의미한다. 즉, 현재 void *ptr의 경우 numptr이 담고 있는 NULL을 담고 있다고 보면 된다
해당 그림을 확인해보면, 처음 ptr의 값은 0 즉 numPtr의 NULL값만 그대로 매개변수로 그대로 받아 온 것이다! 동적할당한 후 그 주솟값만 교체했을 뿐 실질적으로 함수 밖에 있는 포인터 변수 numptr에는 아무런 변화가 일어나지 않는 것이다! 따라서, 함수가 종료되면, 자동으로 사라지는 ptr은 아무런 도움이 되지 않고 있는 것이다!
- 해결책: 이중포인터 매개변수로 받기!
함수를 선언하고, 매개변수를 만드면, main의 함수가 넘어가는 것이 아닌, 매개변수를 스택에 생선 후 입력한 값만 받아오는 것을 기억해야 한다!
#include <stdio.h>
#include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일
void allocMemory(void **ptr, int size) // 반환값 없음, void 이중 포인터 매개변수 지정
{
*ptr = malloc(size); // void **ptr을 역참조하여 void *ptr에 메모리 할당
}
int main()
{
long long *numPtr=NULL;
// 단일 포인터 long long *numPtr의 메모리 주소는 long long **와 같음, 할당할 크기도 넣음
allocMemory((void**)&numPtr, sizeof(long long)); //longlong과 void가 서로 호환되지 않기 때문에
//사전에 void**식으로 인자를 넘기는 것이다.
*numPtr = 10;
printf("%lld\n", *numPtr);
free(numPtr); // 동적 메모리 해제
return 0;
}
해당 코드를 살펴보면, 포인터의 주솟값을 (void**)&numptr 형식으로 넘겨주고, **ptr(이중포인터 변수)변수 선언을 통해 값을 받는 것을 확인할 수 있다. 즉, void **ptr에는 이전처럼 NULL을 인자로 받은 것이 아닌, 실질적인 *numPtr의 포인터 변수의 주솟값을 인자로 받은 것이다. 따라서, *ptr=malloc(size)는 실질적으로 밖에 있는 *numPtr에 동적할당의 주솟값을 입력하게 되고, 이는 함수가 종료되더라도, 실질적으로 *numPtr에 주솟값을 입력했기에 영향력이 지속되는 것이다!
위 그림처럼, 각 포인터의 역참조값을 잘 추적하는 것이 중요하다!
- 코드 출처: 코딩도장