C++ new와 malloc의 차이

mingu Lee·2025년 11월 19일

CS

목록 보기
2/21

C++에서 동적 메모리를 할당하는 대표적인 방법은 new 계열과 C 스타일의 malloc 계열이다.

둘 다 런타임에 원하는 크기만큼 메모리를 요청하는 것이지만, 의미와 사용 목적이 다르다.

1. 공통점


1-1. 동적 메모리 할당


int* p1 = new int;                    // C++ 스타일
int* p2 = (int*)malloc(sizeof(int));  // C 스타일
  • 컴파일이 아닌 런타임에 메모리 크기를 결정
  • 보통 heap 영역의 메모리를 할당받아 가져옴
  • 포인터를 반환하고, 사용이 끝나면 직접 해제해야 함
    • new -> delete
    • malloc -> free

1-2. 메모리 누수


int* p = new int(10);
// delete p;  // 안 하면 누수

int* q = (int*)malloc(sizeof(int));
// free(q);   // 안 하면 누수
  • 둘 다 수동 관리이므로, 해제를 하지 않을 시 메모리 누수가 발생
  • 현대 C++에서는 가능하면 스마트 포인터를 사용하여 RAII로 관리하는 것을 권장

2. 차이점


2-1. 언어 기능 vs 라이브러리 함수


  • new는 C++ 언어에 내장된 연산자
    • 사이즈 지정이 따로 필요 없음
    • Type T에 알맞는 사이즈로 할당
  • malloc은 C 표준 라이브러리 함수이며, cstdlib에 선언
    • 함수 파라미터로 사이즈 값을 주어야 함
    • 파라미터 값에 따라 메모리 크기를 조절 가능

2-2. 초기화 동작


new

Microsoft의 공식 문서를 보면 new 연산자의 정의는 다음과 같다.

즉, 메모리를 할당하고 개체에 적합한 형태로 초기화를 해서 return 한다.

malloc

malloc의 공식 문서 내용은 다음과 같다.

즉, malloc은 단순히 메모리만 빌린다.

그 안의 값은 그 전에 무엇이 있던 그대로(쓰레기 값)이 들어있고, 초기화가 필요하면 프로그래머가 직접 해야 한다.

int* p = (int*)malloc(sizeof(int));
if (p) *p = 0; // 직접 대입

2-3. 타입 캐스팅


new

int* p = new int;       // int* 반환
double* d = new double; // double* 반환
  • new T의 결과는 자동으로 T* 타입
  • 별도의 캐스팅이 필요 없기에 타입 안전

malloc

int* p = (int*)malloc(sizeof(int));  // C 스타일 캐스팅
// C++에선 static_cast<int*>(malloc(...)) 권장
  • malloc은 기본적으로 void* 포인터를 반환
  • 명시적으로 캐스팅을 해야함

2-4. 생성자/소멸자 호출 여부


new

struct Player
{
    Player() { /* 생성자 */ }
    ~Player() { /* 소멸자 */ }
};

Player* p = new Player;   // 생성자 호출
delete p;                 // 소멸자 호출
  • new
    • 메모리를 할당
    • 그 메모리 위에서 생성자 호출
  • delete
    • 소멸자 호출
    • 메모리 해제

즉, new/delete는 생명 주기를 가진 객체를 다룬다.

malloc

Player* p = (Player*)malloc(sizeof(Player));
// 생성자 호출 안 됨

free(p);
// 소멸자도 호출 안 됨
  • malloc/free는 생성자/소멸자를 전혀 호출하지 않음
  • 따라서 생성자/소멸자가 있는 타입을 malloc/free로 관리하는 것은 일반적으로 사용하지 말아야 함

2-5. 실패 시 동작


new

공식 문서를 보면 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로 예외 처리가 가능하다.

malloc

공식 문서를 보면 사용 가능한 메모리가 부족한 경우 널 포인터(null pointer)을 반환한다.

즉, malloc의 경우 try-catch를 사용하지 않고 if 문으로 실패 여부를 검사해서 처리할 수 있다.

int* p = (int*)malloc();
if (!p)
{
    // 실패 처리
}
  • malloc은 실패 시 NULL (C++에서는 nullptr)을 반환
  • 예외는 throw 하지 않음

3. 결론


  • 공통점
    • 둘 다 동적 메모리 할당
    • 포인터 반환, 해제 안 하면 메모리 누수
  • 차이점
    • new는 C++ 객체 생성, 생성자/소멸자 호출 및 타입 안전
    • malloc은 메모리 할당만 해주고, 생성자/소멸자/타입과 무관
    • 할당 실패 시 new는 기본적으로 예외, mallocNULL 반환

한 줄 요약:

C++에서 new는 '객체를 만든다', malloc은 '메모리만 할당한다'

profile
Github: https://github.com/dlalsrn

0개의 댓글