계속해서 작성중 입니다.
Malloc & new
- malloc은 초기값을 설정할 수 없다, new는 가능하다
- malloc은 생성자가 호출되지 않는다, new는 생성자가 호출된다
eh vector constructor iterator에서 생성자 호출?
- malloc은 Realloc으로 메모리블럭의 재할당이 가능하다, new도 실행하다?
구글링을 하면 new는 realloc이 되지 않는다는 글이 많다.
물론 사용안하는게 정신건강에 좋겠지만
그래도 실행은 되지 않을까? 하는 마음에 테스트 해봤다
밑의 코드로 malloc에서 realloc을 하였을 때, new에서 realloc을 하였을 때 를 메모리 디버깅으로 확인해 볼것이다
먼저 malloc에서 realloc일때다
realloc이 다른 주소를 뱉어내는 바람에 원래 들어 있었던 값 9가 다른 주소로 옮겨지는건 확인했지만
우리가 원한 16바이트 만큼 할당이 된건지 알 수 없다
위의 사진에서 realloc으로 재할당 받는걸 볼 수 있다
저 일정하게 채워져 있는 cd와 fd가 무슨 뜻이 있을거 같아서 검색해봤는데 힙에서 넣어주는 값이라고 한다
앞뒤의 fd는 가드 바이트라 하고 cd는 초기화가 되지 않았다는 뜻이라한다
이 글에 자세히 나와있다
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=ruvendix&logNo=220905335341
아무튼 이제 new로 확인해보겠다
마찬가지로 원래 있던 값 9가 있으며 앞뒤로 가드바이트가 있으며 빈 영역에 cd로 채워져있다
이건 realloc이 실행됬다고 생각을 한다
new도 realloc이 되기는 한다
- mallock과 new의 반환형
malloc은 void * 를 반환한다
new는 자료형을 추가로 입력받아 자동으로 캐스팅하여 반환해준다
근데 사실 차이까지라고 해야 하나 싶다 그럴거면 그냥 이름도 차이난다고 하지
- new는 내부적으로 malloc을 사용한다
위에 있는 코드를 어셈블리어로 F11을 눌러서 계속 들어가 확인해 보겠다
1. new의 실체인 operator new가 call이 된다
2. operator new가 있는 곳으로 간다
3. 들어가보면 malloc이 나와있다
4. 과연 같은 malloc일까? 하여 malloc의 실행 주소가 같은지 확인해본다
5. 먼저 new의 malloc이다
6. malloc의 malloc이다
7. 두 함수 모두 0172E340 부터 malloc이 실행된다 이를 통해 같은 malloc이라고 생각을 하고
new의 구현에 있어서 다르겠지만 현재 사용하는 VC++의 new는 내부에서 malloc이 실행된다고 생각한다
- __declspec(allocator) [진행중]
먼저 New가 실행시에 실행되는 함수 operator new이다
_VCRT_ALLOCATOR 이 __declspec(allocator) 으로 define되어 있다
이번엔 malloc의 실 함수이다
여기도 비슷하게 생긴 _CRTALLOCATOR 이란게 있다
여기도 __declspec(allocator)이 나온다!
두개에 모두 들어있기도 하고 ALLOCATOR라는 단어가 들어있어서
메모리 할당 요청에 근접한 기능이 있는가 해서 알아보았다
https://docs.microsoft.com/ko-kr/cpp/cpp/declspec?view=msvc-160
__declspec 이란 대강 뒤에 붙는(ex 위에서 allocator) 특성? 같은걸 저장소 클래스에 지정할 수 있게 해주는 키워드 같다
그럼 이 allocator가 특성이라 하니 살펴봤다
https://docs.microsoft.com/ko-kr/cpp/cpp/allocator?view=msvc-160
allocator 선언 지정자는 사용자 지정 메모리 할당 함수에 적용 되어 ETW(Windows용 이벤트 추적) (ETW)를 통해 할당을 표시할 수 있습니다.
잘 모르겠지만 allocator라는 특성을 설정하고 ETW로 무언가 디버깅?? 같은걸 할수 있다는 말 같은데
ETW 문서도 보았다
https://docs.microsoft.com/ko-kr/windows-hardware/drivers/devtest/event-tracing-for-windows--etw-
https://docs.microsoft.com/ko-kr/visualstudio/profiling/custom-native-etw-heap-events?view=vs-2019
ETW (Windows 용 이벤트 추적)는 사용자 모드 응용 프로그램 및 커널 모드 드라이버에서 발생하는 이벤트를 추적하고 기록하는 메커니즘을 제공합니다. ETW는 Windows 운영 체제에서 구현되며 개발자에게 빠르고 안정적이며 다양한 이벤트 추적 기능 세트를 제공합니다.
Add the __declspec(allocator)
decorator to any function in your custom heap manager that returns a pointer to newly allocated heap memory. This decorator allows the tool to correctly identify the type of the memory being returned. For example:
최종적으로 보아하니 __declspec(allocator)는 직접적인 할당의 요청 이런게 아니라 그냥 단순 속성을 정하고
디버깅을 할때? 그런 용도로 사용되는거 같다..
V가 붙고 안붙고의 차이는 모르겠다..
delete [ ]
new로 할당 받은 배열 포인터의 해제다
delete [ ] 포인터 로 해제를 한다
근데 사실 delete만 사용해도 해제가 된다
[객체 배열 같은 경우에는 소멸자 문제가 있음]
근데 우리가 몇개의 배열을 할당 받은 줄 알고 시작주소만 넘겨주어도 모두 해제가 이루어지는가?? 궁금했다
일단 사전 지식을 알아야 이해할 수 있었다
1. 일단 하나의 프로그램이 시작되면 그 프로그램에게 하나의 힙메모리가 주어진다 이는 Default Heap이라 한다
(Default Heap, Default process heap 이렇게 부르는 듯 하다)
2. Default Heap은 다양한 메모리크기의 요청에 응답하려 여러 메모리의 크기로 나누어져있다
이 나누어진 메모리들을 메모리 블럭 이라 한다
3. Windows에서 이 Default Heap을 관리하는 Heap manager라는 시스템이 있다
4. 우리가 힙에 메모리할당을 요청하면 이 HeapManager가 Default Heap에서
요청한 크기에 알맞는 메모리블럭을 찾으면 그 첫번째 주소를 반환한다
5. 이때 Heap manager에 지금 할당해 준 크기를 저장한다
우리가 free나 delete로 시작주소만 넘겨도 모두 해제가 될 수 있었던 이유는
저 Heap manager에 할당해 준 크기가 저장되어 있기 때문이였다
[ 힙매니저에 저장되는 방식이라던지, 어디에있고 어떻게 관리되는 부분은 아직 내게 필요하지 않은 부분같다 ]
6. 여기까지 malloc 의 대략적인 할당 과정이다.
※ new의 동적할당과 new의 배열동적할당 어셈블리 차이 확인하기
작성시 많은 도움이 된 글
https://kfgd.tistory.com/18?category=974115
검증이 어렵고 어려운 내용이 많아 틀린부분이 많을거 같습니다.
잘못된 부분이 있다면 알려주시면 감사드립니다.
'C++ > 헷갈리는것들 정리' 카테고리의 다른 글
복사생성자가 왜 호출이 되지 않나? (copy elision) (0) | 2022.03.28 |
---|---|
클래스의 전방선언하면서 내가 착각하고 있었던 것 (0) | 2022.01.29 |
주소 관련 (0) | 2021.07.15 |