동적 할당인 new를 사용하면 delete를 사용하여 메모리 해제를 해 주어야하고,
new[]를 사용하면 delete[]를 사용하여 메모리를 해 주어야 한다는 사실은 C++개발자라면 누구나 알고 있습니다.
하지만 new와 new[]가 내부적으로는 완전히 다른 방식으로 동작하게 됩니다.
1. new의 내부 동작
new를 사용하여 메모리 할당을 하게되면 내부적으로는 malloc을,
delete를 사용하여 메모리를 해제하게 되면 내부적으로는 free를 호출하게 됩니다.
int*p = new int; -> malloc(sizeof(int))
malloc은 Heap Manager에게 메모리 할당을 요청하고, Heap Manager는 관리하고 있는 힙에서 적절하게 4바이트만큼의 메모리 블록을 찾은 후, 해당 블록의 메모리주소를 반환해줍니다.
그래서 int* p 는 HeapManager가 할당해준 메모리 블록의 주소를 가지게 되는 것입니다.
Heap Manager는 이렇게 메모리 주소를 반환하고 해당블록의 주소를 할당내역에 사이즈와 함께 추가합니다.
그리고 free가 일어날 때, 할당내역에서 해당 메모리 주소를 찾아 할당된 사이즈만큼 해제하게 됩니다.
2. new []의 내부동작
new[]는 할당되는 사이즈가 new와 다릅니다.
int 한개를 멤버변수로 가진 class Test 가 있다고 가정했을 때,
Test * mTest = new Test[2]; 는 내부적으로
malloc (2 * sizeof(Test) + 4)가 됩니다.
+4는 x86과 x64에 관계없이 4 입니다. (배열 요소 개수가 42억개를 넘는 경우가 없을것이기 때문...! )
Heap Manager는 요청받은 만큼 12 바이트를 할당하고, 해당 주소를 반환하는데,
이 때, new[] operater는 받은 주소 + 4의 주소를 반환하게 됩니다.
delete[] 가 호출이 되었을 때도 마찬가지로 컴파일러는 mTest가 가리키는 주소에서 4만큼 빼어서 배열 요소가 몇 개인지를 알아냅니다.
(소멸자 호출을 위함) 그리고, 반복문을 돌면서 소멸자를 호출해 준 후, free를 호출해 주는데 이 때도 mTest가 가리키는 주소에서 4만큼 뺀 주소를 넘겨줍니다.
하지만 소멸자가 아예 존재하지않는 기본타입의 배열인 경우에는 추가영역 4바이트가 불필요 하게 됩니다.
이런 경우에는 배열 요소 갯수를 저장하지 않고, new와 같은 방식으로 동작하게 됩니다.
'STUDY > C++' 카테고리의 다른 글
std::map에 관한 고찰 (0) | 2020.04.16 |
---|---|
선언과 정의에 따른 메모리 (0) | 2019.06.23 |
[ STL ] 표준 시퀀스 컨테이너(vector, deque, list) (0) | 2018.03.12 |
상속과 동적,정적바인딩 (0) | 2018.02.28 |
Class내에서의 Static (0) | 2018.02.27 |