C 언어에서는 void 포인터가 객체 포인터 타입으로 암시적으로(implicitly) 변환됩니다. C89 표준에서 malloc() 함수는 void*를 반환하며, 그보다 이전 버전의 C에서는 char*를 반환했습니다. 반면 C++에서는 void*를 다른 포인터 타입으로 암시적으로 변환하는 것이 허용되지 않기 때문에, malloc()이 반환한 값을 대입하려면 명시적 캐스팅(explicit casting)이 반드시 필요합니다.
C 언어에서의 메모리 할당 문법
pointer_name = malloc(size);
여기서 각 구성 요소는 다음과 같습니다.
pointer_name − 포인터에 붙이는 임의의 이름입니다.
size − 할당할 메모리의 크기(바이트 단위)입니다.
C 언어에서의 malloc() 예제
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 4, i, *p, s = 0;
p = malloc(n * sizeof(int));
if(p == NULL) {
printf("\nError! memory not allocated.");
exit(0);
}
printf("\nEnter elements of array : ");
for(i = 0; i < n; ++i) {
scanf("%d", p + i);
s += *(p + i);
}
printf("\nSum : %d", s);
return 0;
}실행 결과
Enter elements of array : 2 28 12 32 Sum : 74
위 C 언어 예제에서처럼 void*는 자동으로 int*로 변환되므로 캐스팅 없이도 정상적으로 컴파일됩니다. 물론 명시적으로 캐스팅하더라도 오류는 발생하지 않습니다.
C++ 언어에서의 메모리 할당 문법
pointer_name = (cast-type*) malloc(size);
여기서 각 구성 요소는 다음과 같습니다.
pointer_name − 포인터에 붙이는 임의의 이름입니다.
cast-type − malloc()이 할당한 메모리를 변환하고자 하는 데이터 타입입니다.
size − 할당할 메모리의 크기(바이트 단위)입니다.
C++ 언어에서의 malloc() 예제
#include <iostream>
#include <cstdlib>
using namespace std;
int main() {
int n = 4, i, *p, s = 0;
p = (int *)malloc(n * sizeof(int));
if(p == NULL) {
cout << "\nError! memory not allocated.";
exit(0);
}
cout << "\nEnter elements of array : ";
for(i = 0; i < n; ++i) {
cin >> *(p + i);
s += *(p + i);
}
cout << "\nSum : " << s;
return 0;
}실행 결과
Enter elements of array : 28 65 3 8 Sum : 104
위 C++ 예제에서 만약 명시적 캐스팅을 하지 않으면 컴파일러는 다음과 같은 오류를 출력합니다.
error: invalid conversion from ‘void*’ to ‘int*’ [-fpermissive] p = malloc(n * sizeof(int));
정리
핵심 차이는 두 언어의 타입 변환 규칙에 있습니다. C에서는 void*에서 다른 객체 포인터 타입으로의 변환이 암시적으로 허용되지만, C++는 타입 안전성을 중시하기 때문에 이러한 암시적 변환을 금지하고 개발자가 의도를 명확히 드러내도록 명시적 캐스팅을 요구합니다. 참고로 C++에서는 malloc()보다 new 연산자를 사용하는 것이 타입 안전성 면에서 더 권장되는 방식입니다.