Coding/Unreal, C++

malloc(), new

'new' keyword

  • new는 C++에서 등장한 키워드로 C의 malloc()을 대신한다.
A* ptr = (A*)malloc(sizeof(A)); // malloc()을 활용한 동적 메모리 할당
A* ptr = new A; // new을 활용한 동적 메모리 할당
  • 기본적으로 malloc()과 new의 차이점은 2개다.
    • malloc()은 함수지만 new는 연산자다. 그래서 new는 연산자 오버로딩도 가능하다.
    • new는 클래스의 생성자를 호출해준다.
  • 이로 미뤄보아 new 연산자를 굳이 추가한 이유는 2가지를 들 수 있겠다.
    1. malloc()에 비해 문법이 간결하다.
    2. OOP는 C++의 주요 컨셉 중 하나이고 new는 오브젝트를 동적할당할 때 생성자 호출을 간단하게 구현해준다. 

그렇다면 'new'는 malloc()을 래핑한 연산자인가?

  • new도 동적할당을 해주는데, 그렇다면 new == malloc() + 생성자 호출이라고 이해해도 될까?
  • 많은 환경에서 그렇게 정의되고 있지만, 이정도만 이해하기엔 아쉬운 점이 있다. 예를 들어보자.
  • VC++에서 new는 다음과 같이 동작한다.
    1. new가 malloc()을 호출한다.
    2. malloc()이 HeapAlloc()을 호출한다.
  • HeapAlloc()은 윈도우 환경에서 특정 힙에 메모리를 할당해주는 함수다. HeapAlloc()은 따로 설정을 안해주면 메모리 할당시에 lock/unlock 과정을 거친다. 메모리 할당 시에 race condition이 걸릴 수 있기 때문이다.
  • 근데 우리가 만드는 프로그램이 윈도우의 싱글 쓰레드로 돌아간다면 어떨까? 그렇다면 HeapAlloc()의 Lock/Unlock은 쓸데없는 과정이다. 그렇다면 프로그래머는 new 연산자를 오버로딩해서 최적화를 꾀할 수 있다.
  • 라이브러리의 malloc()을 쓰지 않고 바로 HeapCreate()를 통해 Heap을 만들고 HeapAlloc()에 HEAP_NO_SERIALIZED 플래그를 넣는 것이다.
  • 그러니까 new는 보통 내부에서 malloc()을 호출하지만 그건 그냥 편의를 위한 것이다. malloc()은 거의 모든 OS에 구현되어 있을테니, new가 메모리할당에 malloc()을 쓰면 new를 위해서 굳이 플랫폼 별로 메모리 할당 코드를 짤 필요가 없기 때문이다. 하지만 약속일 뿐이고 malloc() 사용이 강제되지는 않는다.

References

 

Does ::operator new(size_t) use malloc()?

Does ::operator new(size_t) call malloc() internally, or does it use system calls / OS-specific library calls directly? What does the C++ standard say? In this answer it says that: malloc() is

stackoverflow.com

 

HeapAlloc function (heapapi.h) - Win32 apps

Allocates a block of memory from a heap. The allocated memory is not movable.

docs.microsoft.com