malloc/free와 C++ 계열 new/delete의 차이malloc↔delete, new↔free, new[]↔delete)malloc이 C++ 객체에 바로 쓰기 위험한 이유를 “생성자/소멸자”로 설명할 수 있다.new[]에는 왜 반드시 delete[]가 필요한지 설명할 수 있다.malloc/free는 함수이며, “원시 메모리(raw bytes)”를 다룹니다.malloc(n)은 n 바이트를 확보하고, 시작 주소를 void*로 반환합니다.#include <cstdlib>
void* ptr = std::malloc(1000); // 1000바이트 확보
// ... 바이트 단위로 사용 ...
std::free(ptr); // malloc으로 잡았으면 free로 해제
struct Monster {
Monster() : hp(100) {} // 생성자
~Monster() {} // 소멸자(예: 자원 정리)
int hp = 0;
};
Monster* m = static_cast<Monster*>(std::malloc(sizeof(Monster)));
// ❌ 여기서는 Monster() 생성자가 호출되지 않음 → hp가 100이라는 보장이 없다
std::free(m); // ❌ 소멸자도 호출되지 않음
결론: C++ “객체”를 다룰 때는 malloc/free를 기본으로 쓰지 않습니다. (특수한 경우는 나중에)
new/delete는 연산자이며,new T(...)는 “메모리 확보 + 생성자 호출”delete p는 “소멸자 호출 + 메모리 해제”Monster* m = new Monster(); // 생성자 호출됨
delete m; // 소멸자 호출됨
┌─────────────────────────────────────┬────────────────────────────────────────┐
│ malloc/free │ new/delete │
├─────────────────────────────────────┼────────────────────────────────────────┤
│ 함수 │ 연산자 │
│ 바이트 메모리 확보/해제 │ 메모리 + 생성자/소멸자(객체 생명주기) │
│ void* 반환(캐스팅 필요) │ 타입 포인터 반환 │
│ C 스타일 │ C++ 스타일(객체에는 보통 이쪽) │
└─────────────────────────────────────┴────────────────────────────────────────┘
new T[N]은 N개를 연속으로 할당하고, (일반적으로) 생성자 N번 호출delete[]는 (일반적으로) 소멸자 N번 호출 후 해제new[]로 잡은 것을 delete로 지우면 동작이 깨질 수 있습니다(UB)Monster* arr = new Monster[5];
arr[0].hp = 100;
delete[] arr; // ✅ new[]에는 delete[]
이 3가지는 “가끔 돌아가는 것처럼 보여도” 위험합니다.
std::malloc ↔ deletenew ↔ std::freenew[] ↔ delete (또는 반대)malloc이 “메모리는 잡는데, 객체는 못 만든다”는 말의 의미는?new와 delete가 각각 “추가로 해주는 일”은 무엇인가?new[]에 delete[]가 필수인 이유는?