Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C/C++에서 void 포인터를 삭제하는 것은 안전할까? 위험한 이유와 예제

void 포인터란 무엇인가?

void 포인터(void pointer)는 특정 데이터 타입과 연결되어 있지 않은 포인터를 의미합니다. 메모리상의 데이터 위치, 즉 변수의 주소를 가리키지만, 그 대상이 int형인지 float형인지 등의 타입 정보는 갖고 있지 않습니다. 이러한 특성 때문에 범용 포인터(general purpose pointer)라고도 불립니다.

void 포인터 삭제가 안전하지 않은 이유

C++에서 void 포인터를 delete로 삭제하는 것은 안전하지 않으며, 미정의 동작(undefined behavior)을 초래할 수 있습니다. 그 이유는 다음과 같습니다.

  • delete 연산자는 소멸 대상 객체의 소멸자(destructor)를 반드시 호출해야 합니다.
  • 그러나 void 포인터에는 객체의 실제 타입 정보가 없으므로, 컴파일러는 어떤 소멸자를 호출해야 할지 판단할 수 없습니다.
  • 특히 클래스 타입 객체의 경우 소멸자가 호출되지 않으면 힙 영역의 자원이 해제되지 않아 메모리 누수(memory leak)와 같은 심각한 문제가 발생할 수 있습니다.

따라서 동적으로 할당한 메모리를 해제할 때는 반드시 올바른 타입의 포인터로 변환하여 사용해야 합니다. 참고로 C 언어의 free() 함수는 매개변수로 void 포인터를 받기 때문에, malloc으로 할당한 메모리를 void 포인터로 해제하는 것은 문제가 되지 않습니다. 문제는 오직 C++의 delete에서 발생합니다.

void 포인터 기본 예제

다음은 void 포인터를 선언하고, 형 변환(casting)을 통해 서로 다른 타입의 변수를 가리키게 하는 간단한 예제입니다.

#include <stdio.h>

int main() {
    int a = 7;
    float b = 7.6;
    void *p;

    p = &a;
    printf("Integer variable is = %d", *((int*) p));

    p = &b;
    printf("\nFloat variable is = %f", *((float*) p));

    return 0;
}

실행 결과

Integer variable is = 7
Float variable is = 7.600000

위 예제에서 볼 수 있듯이 하나의 void 포인터 p가 int형 변수와 float형 변수를 번갈아 가리킬 수 있습니다. 단, 값을 읽거나 수정할 때는 반드시 올바른 타입으로 명시적 형 변환을 해주어야 한다는 점을 기억하세요.