48.3 이중 포인터 매개변수 사용하기
지금까지 함수에서 포인터 매개변수를 이용해서 정수, 실수 등의 값을 가져왔습니다. 그러면 일반적인 값 대신 포인터(메모리 주소)를 얻어오려면 어떻게 해야 할까요?
먼저 함수에 포인터를 넘겨준 뒤 메모리를 할당해보겠습니다. 다음 내용을 소스 코드 편집 창에 입력한 뒤 F5 키를 눌러서 디버깅 모드로 실행해보세요.
parameter_single_pointer.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; }
실행 결과
0xC0000005: 0x00000000 위치를 기록하는 동안 액세스 위반이 발생했습니다.
잘 될 것 같지만 실행을 해보면 에러가 발생합니다. 왜 그럴까요? void allocMemory(void *ptr, int size)와 같이 매개변수를 void 포인터로 지정한 뒤 ptr에 메모리를 할당했습니다. 하지만 ptr에 메모리를 할당해봐야 allocMemory 함수를 벗어나면 사용할 수가 없습니다. 결국 메모리 누수가 발생하지요.
void allocMemory(void *ptr, int size) // 반환값 없음, void 포인터 매개변수 지정 { ptr = malloc(size); // ptr은 allocMemory를 벗어나면 사용할 수 없음 }
이번에는 이중 포인터를 사용하여 함수 안에서 메모리를 할당한 뒤 가져와보겠습니다.
parameter_double_pointer.c
#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; // 단일 포인터 long long *numPtr의 메모리 주소는 long long **와 같음, 할당할 크기도 넣음 allocMemory(&numPtr, sizeof(long long)); *numPtr = 10; printf("%lld\n", *numPtr); free(numPtr); // 동적 메모리 해제 return 0; }
실행 결과
10
allocMemory 함수를 만들 때 void allocMemory(void **ptr, int size)와 같이 void 이중 포인터 ptr을 받도록 만듭니다. 물론 할당할 메모리 크기도 알아야 하므로 size도 함께 받습니다.
함수 안에서는 매개변수 void **ptr를 역참조하여 void *ptr이 되도록 만든 뒤 malloc 함수로 메모리를 할당합니다.
void allocMemory(void **ptr, int size) // 반환값 없음, void 이중 포인터 매개변수 지정 { *ptr = malloc(size); // void **ptr을 역참조하여 void *ptr에 메모리 할당 }
이제 long long *numPtr;와 같은 단일 포인터를 선언한 뒤 numPtr의 메모리 주소를 구해서 allocMemory 함수에 넣어줍니다. 즉, long long *numPtr;의 메모리 주소는 long long **과 같으므로 매개변수 void **ptr로 받을 수 있습니다.
long long *numPtr; // 단일 포인터 long long *numPtr의 메모리 주소는 long long **와 같음, 할당할 크기도 넣음 allocMemory(&numPtr, sizeof(long long)); *numPtr = 10; printf("%lld\n", *numPtr); free(numPtr); // 동적 메모리 해제
다음과 같이 매개변수 void **ptr을 역참조하여 실제로는 numPtr에 메모리를 할당하게 됩니다.