본문 바로가기

C언어

[C]void 포인터에 자료형 할당하기

일반적인 자료형 할당하기

void 포인터는 자유로운 영혼이다. 

void 포인터를 다른 자료형으로 변환하면 역참조를 할 수 있다.

 

*(할당받은 자료형 *)ptr

 

역참조란, 포인터형으로 선언된 변수에다가 *를 붙여 값을 얻어낸 과정

 

 

#include <stdio.h>

int main()
{
    int num1 = 10;
    float num2 = 3.5f;
    char c1 = 'a';
    void *ptr;

    ptr = &num1;    // num1의 메모리 주소를 void 포인터 ptr에 저장
    // printf("%d\n", *ptr);         // 컴파일 에러
    printf("%d\n", *(int *)ptr);     // 10: void 포인터를 int 포인터로 변환한 뒤 역참조

    ptr = &num2;    // num2의 메모리 주소를 void 포인터 ptr에 저장
    // printf("%f\n", *ptr);         // 컴파일 에러
    printf("%f\n", *(float *)ptr);   // 3.500000: void 포인터를 float 포인터로 변환한 뒤 역참조

    ptr = &c1;      // c1의 메모리 주소를 void 포인터 ptr에 저장
    // printf("%c\n", *ptr);         // 컴파일 에러
    printf("%c\n", *(char *)ptr);    // a: void 포인터를 char 포인터로 변환한 뒤 역참조

    return 0;
}

 

 


구조체 포인터  할당하기

 

struct에도 마찬가지이다. 

할당받은 자료형이 특정 struct로 대체되었을 뿐이다.

 

(struct Data *)void_ptr

((struct Data *)void_ptr)->member 로 쓴다는 것만 조심하면 된다.

#include <stdio.h>
#include <stdlib.h>    // malloc, free 함수가 선언된 헤더 파일

struct Data {
    char c1;
    int num1;
};

int main()
{
    struct Data *d1 = malloc(sizeof(struct Data));    // 포인터에 구조체 크기만큼 메모리 할당
    void *ptr;    // void 포인터 선언

    d1->c1 = 'a';
    d1->num1 = 10;

    ptr = d1;    // void 포인터에 d1 할당. 포인터 자료형이 달라도 컴파일 경고가 발생하지 않음.
	
    ((struct Data *)ptr)->num1 = 5;
    
    printf("%c\n", ((struct Data *)ptr)->c1);      // 'a' : 구조체 포인터로 변환하여 멤버에 접근
    printf("%d\n", ((struct Data *)ptr)->num1);    // 5  : 구조체 포인터로 변환하여 멤버에 접근

    free(d1);    // 동적 메모리 해제

    return 0;
}

여기서 printf 할 때를 주목해야 한다.

void 포인터 ptr은 struct Data 포인터를 할당받았다.

void 포인터 ptr로 구조체 포인터 멤버에 접근하고자 한다면 (struct Data *)를 ptr 앞에 명시해주고 다같이 묶은

((struct Data *)ptr)->로 접근해야 한다.

 

만일 괄호를 빼먹고 (struct Data *)ptr->num1로 사용한다면 동작하지 않는다.