46.3 void 포인터 반환하기
지금까지 반환값의 자료형을 정해서 값을 가져왔습니다. 그럼 자료형에 상관없이 값을 꺼내오고 싶다면 어떻게 해야 할까요? 이때는 어떤 자료형으로 된 포인터든 넣을 수 있는 void 포인터를 활용하면 편리합니다.
이번에는 void 포인터를 반환하고 사용하는 방법을 알아보겠습니다. 다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요.
return_void_pointer.c
#define _CRT_SECURE_NO_WARNINGS // strcpy 보안 경고로 인한 컴파일 에러 방지 #include <stdio.h> #include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일 #include <string.h> // strcpy 함수가 선언된 헤더 파일 void *allocMemory() // void 포인터를 반환하는 allocMemory 함수 정의 { void *ptr = malloc(100); // 100바이트만큼 동적 메모리 할당 return ptr; // void 포인터 반환 } int main() { char *s1 = allocMemory(); // void 포인터를 char 포인터에 넣어서 문자열처럼 사용 strcpy(s1, "Hello, world!"); // s1에 Hello, world! 복사 printf("%s\n", s1); // Hello, world! free(s1); // 동적 메모리 해제 int *numPtr1 = allocMemory(); // void 포인터를 int 포인터에 넣어서 정수 배열처럼 사용 numPtr1[0] = 10; // 첫 번째 요소에 10 저장 numPtr1[1] = 20; // 두 번째 요소에 20 저장 printf("%d %d\n", numPtr1[0], numPtr1[1]); // 10 20 free(numPtr1); // 동적 메모리 해제 return 0; }
실행 결과
Hello, world! 10 20
먼저 void *allocMemory()와 같이 함수의 반환값 자료형을 void 포인터로 지정합니다. 그리고 함수 안에서는 void 포인터에 malloc으로 100바이트만큼 메모리를 할당한 뒤 반환합니다.
void *allocMemory() // void 포인터를 반환하는 allocMemory 함수 정의 { void *ptr = malloc(100); // 100바이트만큼 동적 메모리 할당 return ptr; // void 포인터 반환 }
void 포인터는 강제로 변환을 하지 않아도 다양한 형태의 포인터에 넣을 수 있다고 했습니다.
먼저 allocMemory에서 반환된 void 포인터를 문자열 포인터에 넣어서 문자열처럼 사용합니다.
char *s1 = allocMemory(); // void 포인터를 char 포인터에 넣어서 문자열처럼 사용 strcpy(s1, "Hello, world!"); // s1에 Hello, world! 복사 printf("%s\n", s1); // Hello, world! free(s1); // 동적 메모리 해제
다시 allocMemory에서 반환된 void 포인터를 int 포인터에 넣어서 정수 배열처럼 사용할 수도 있습니다. 단, allocMemory에서 100바이트만큼 메모리를 할당했으므로 100바이트 이상 값을 넣으면 안 됩니다.
int *numPtr1 = allocMemory(); // void 포인터를 int 포인터에 넣어서 정수 배열처럼 사용 numPtr1[0] = 10; // 첫 번째 요소에 10 저장 numPtr1[1] = 20; // 두 번째 요소에 20 저장 printf("%d %d\n", numPtr1[0], numPtr1[1]); // 10 20 free(numPtr1); // 동적 메모리 해제
allocMemory안에서 malloc를 사용하고 있으므로 allocMemory에서 반환된 포인터를 사용할 때마다 반드시 free 함수로 메모리를 해제해줍니다.
코드를 줄이려면 ptr 변수를 선언하지 않고, malloc 함수를 호출하면서 바로 반환해도 됩니다. 이렇게 하면 malloc 함수에서 반환된 값을 다시 반환합니다.
void *allocMemory() { return malloc(100); // malloc 함수를 호출하면서 바로 반환 }