C++에서 동적 메모리를 할당하는 대표적인 방법은 new 계열과 C 스타일의 malloc 계열이다.
둘 다 런타임에 원하는 크기만큼 메모리를 요청하는 것이지만, 의미와 사용 목적이 다르다.
int* p1 = new int; // C++ 스타일
int* p2 = (int*)malloc(sizeof(int)); // C 스타일
new -> deletemalloc -> freeint* p = new int(10);
// delete p; // 안 하면 누수
int* q = (int*)malloc(sizeof(int));
// free(q); // 안 하면 누수
cstdlib에 선언Microsoft의 공식 문서를 보면 new 연산자의 정의는 다음과 같다.

즉, 메모리를 할당하고 개체에 적합한 형태로 초기화를 해서 return 한다.
malloc의 공식 문서 내용은 다음과 같다.

즉, malloc은 단순히 메모리만 빌린다.
그 안의 값은 그 전에 무엇이 있던 그대로(쓰레기 값)이 들어있고, 초기화가 필요하면 프로그래머가 직접 해야 한다.
int* p = (int*)malloc(sizeof(int));
if (p) *p = 0; // 직접 대입
int* p = new int; // int* 반환
double* d = new double; // double* 반환
new T의 결과는 자동으로 T* 타입int* p = (int*)malloc(sizeof(int)); // C 스타일 캐스팅
// C++에선 static_cast<int*>(malloc(...)) 권장
void* 포인터를 반환struct Player
{
Player() { /* 생성자 */ }
~Player() { /* 소멸자 */ }
};
Player* p = new Player; // 생성자 호출
delete p; // 소멸자 호출
newdelete즉, new/delete는 생명 주기를 가진 객체를 다룬다.
Player* p = (Player*)malloc(sizeof(Player));
// 생성자 호출 안 됨
free(p);
// 소멸자도 호출 안 됨
malloc/free는 생성자/소멸자를 전혀 호출하지 않음malloc/free로 관리하는 것은 일반적으로 사용하지 말아야 함공식 문서를 보면 new를 실패하면 예외를 throw 한다고 나와 있다.

실패 시 예외가 throw 되므로, 필요하다면 try-catch로 예외 처리를 할 수 있다.
try
{
int* p = new int[1000000000000]; // 매우 큰 할당
}
catch (const std::bad_alloc& e)
{
// 메모리 부족 시 예외 발생
}
new는 할당 실패 시 std::bad_alloc 예외가 발생만약, try-catch를 사용하기 싫다면 nothrow 양식의 new를 사용하면 된다.

nothrow 양식의 new를 사용하는 경우 if로 예외 처리가 가능하다.
공식 문서를 보면 사용 가능한 메모리가 부족한 경우 널 포인터(null pointer)을 반환한다.

즉, malloc의 경우 try-catch를 사용하지 않고 if 문으로 실패 여부를 검사해서 처리할 수 있다.
int* p = (int*)malloc(…);
if (!p)
{
// 실패 처리
}
malloc은 실패 시 NULL (C++에서는 nullptr)을 반환new는 C++ 객체 생성, 생성자/소멸자 호출 및 타입 안전malloc은 메모리 할당만 해주고, 생성자/소멸자/타입과 무관new는 기본적으로 예외, malloc은 NULL 반환