New Vs Malloc
New 와 Malloc에 대하여
공통점
- 두 기능 모두 Heap 영역에 동적 메모리 할당을 요청
- 또한 메모리 누수를 방지하기 위해 각각 delete와 free 호출이 필요
차이점
new
생성자호출 및 할당 영역 초기화- 자료형 타입만큼의 ‘메모리 할당’
- 반환형이 자료형의 포인터 타입
- C++ 제공 ‘연산자’
- 그렇기에 ‘연산자 오버로딩’이 가능함
(커스텀 Alloc이 가능)
- 그렇기에 ‘연산자 오버로딩’이 가능함
malloc
- 메모리 할당만을 해주며, 임의의 초기화 X
- 그렇기에 memcpy,memset 같은 임의의 함수를 통해 초기화하는 편
- 그렇기에 memcpy,memset 같은 임의의 함수를 통해 초기화하는 편
- 임의의 사이즈만큼 ‘메모리 할당’ 가능
- void* 로 반환하는 함수
- 캐스팅하여 사용해야 함
- 캐스팅하여 사용해야 함
세부 비교 표
| 구분 | new (C++) |
malloc (C / C++) |
|---|---|---|
| 소속 | C++ 연산자 (operator) | C 표준 라이브러리 함수 |
| 헤더 | 없음 (언어 키워드) | <stdlib.h> / C++에선 <cstdlib> |
| 반환 타입 | 요청한 타입의 포인터 (예: MyClass*) |
void* → C++에선 형변환 필요 |
| 초기화 | 자동 초기화 / 생성자 호출 - 기본 생성자/지정 생성자 호출 - 내장 타입은 new int()처럼 하면 0 초기화 |
초기화 안 함 (쓰레기 값 그대로) 필요하면 memset 또는 직접 대입해야 함 |
| 생성자/소멸자 | 생성자/소멸자 호출 O | 생성자/소멸자 호출 X |
| 문법 | T* p = new T;T* arr = new T[n]; |
T* p = (T*)malloc(sizeof(T));T* arr = (T*)malloc(sizeof(T) * n); |
| 해제 방식 | delete p; / delete[] arr; |
free(p); |
| 실패 시 동작 | 기본적으로 예외 std::bad_alloc 던짐(nothrow 버전 new(std::nothrow) 쓰면 nullptr 반환) |
nullptr (C에선 NULL) 반환예외 X |
| 크기 인자 | 타입 기준 (new T, new T[n]) → sizeof(T)를 직접 안 씀 |
반드시 바이트 단위 크기 직접 계산 (sizeof(T) * n) |
| 타입 안전성 | 높음 (반환 타입이 명확함) | 낮음 (void* → C++에선 캐스팅 필요) |
| 오버로딩 | operator new / operator delete 오버로딩해서 커스텀 메모리 할당 전략 구현 가능 |
malloc은 일반 함수, 오버로딩 불가.커스텀하려면 따로 함수 작성 |
| 배열 지원 | new[] / delete[] 문법 제공 |
배열 개념 없음. 그냥 크기만큼 바이트를 할당 |
| 재할당 | 직접 지원 X (new에는 realloc 같은 것 없음) |
realloc으로 크기 변경 가능 |
예상 면접 (Sprata_Unreal Camp)
A : 질문자, B : 답변자
A
- Heap 영역에 ‘할당’되었다 하였는데
프로세스 들의 ‘다른 영역’은 무엇이 있을까?
B
- Stack/Data/Code/BSS/Heap이 존재
A
- Stack 영역에 대하여 더 자세히 설명해줄 수 있나?
B
- 함수 내의 매개 변수, 지역 변수에 대한 메모리를 보관하는 공간
- 다른 함수를 호출함으로서, 해당 함수의 주소로 찾아가 필요한 공간만큼 늘어남
- 그렇기에 함수 호출이 깊어지면 스택 포인터가 점점 늘어나게 됨
- 이것이 Heap이나 다른 안전 영역, Guard Page 를 침범하게 되면
프로세스가 정상적인 상태가 아니기에 Kill 당함
A
- 함수 주소의 ‘필요한 공간’을 컴파일 시간에 알 수 있는건가?
B
- ‘매개 변수’, ‘지역 변수’의 크기를 컴파일 시간에 알 수 있으므로 가능
댓글남기기