본문 바로가기

C, C++/C, C++ 잡지식

동적할당 분석해보기(1)

개요

동적할당에 대해서 알아보자

동적할당은 메모리 구조 중에서 힙 영역을 사용해 메모리를 할당하는 방법이다.


malloc과 free

malloc

malloc은 C계열에서 사용하는 가장 기본적이고 많이 사용되는 동적할당 방법이다.

void* 타입을 반환하며 인자로는 할당할 만큼의 크기를 받는다.

void*타입을 반환하기 때문에 malloc으로 메모리를 할당 받은 변수가 가리킬 타입을 사용이 필요할 때 캐스팅 해야 한다.

 

malloc을 통해 할당받은 메모리의 크기

인자로 할당받은 크기 만큼을 정확하게 힙이 확보하는 것은 엄밀히 아니다.

헤더에 used 여부 (free 되었는지), 할당된 크기를 기록하기 때문에 이보다 큰 공간을 할당 받는다.

 

그리고 malloc 시 return받는 포인터 값은 32비트 시스템에서는 8바이트, 64비트 시스템에서는 16바이트의 정렬을 맞춘 주소값이다. 

추가적으로 더 큰 주소값 정렬이 필요하다면, _aligned_malloc을 사용한다.

https://learn.microsoft.com/ko-kr/cpp/c-runtime-library/reference/malloc?view=msvc-170

 

malloc

자세한 정보: malloc

learn.microsoft.com

 

 

free

free는 동적할당의 짝꿍으로, 할당된 메모리를 해제한다.

해제 시에는 처음 할당해서 return받은 주소 값을 넣어주면 된다.

인자로 받은 포인터 주소와 이를 통해 찾은 힙 메모리 블록 메타데이터로 메모리를 해제한다.

 

따라서 p의 정보가 아닌 다른 정보가 들어간다면 힙 관리자 내부 테이블에 등록되지 않은 주소를 참조하려고 하기 때문에 오류가 발생한다.

엄밀히는 힙 관리자에 등록되지 않은 주소이기 때문에 오류가 발생하는 것이다.

https://learn.microsoft.com/ko-kr/cpp/c-runtime-library/reference/free?view=msvc-170

 

free

자세한 정보: 무료

learn.microsoft.com


힙 할당과 해제

힙 공간에 대한 할당과 해제가 실제로 해당 메모리에 대한 접근 자체를 제한시키는 것은 아니다.

논리적 접근 금지일 뿐이다. 따라서 더욱 조심히 사용해야 한다.

 

malloc->HeapAlloc->VirtualAlloc으로 내부적으로 흐르면서, 힙을 처음 할당할 때 HeapCreate를 통해 Reserved 상태로 큰 가상 메모리 블록을 확보한다.

요청(필요할)할 때 Reserved 영역 일부를 Committed 상태로 변환해 물리 메모리를 실제로 붙인다.

free 시에도 바로 decommited 되는 것이 아니므로 OS 관점에서는 페이지가 여전히 Committed 상태이다.

 

따라서 그 주소에 포인터를 통해 직접 접근한다면 오류가 발생하지 않는다.


동적할당 시에 생길 수 있는 문제들

dangling pointer(use after free)

가장 대표적인 동적할당에서 생기는 문제는 dangling pointer이다.

dangling pointer는 이미 해제된 메모리를 여전히 가리키고 있는 포인터를 의미한다.

 

위에서 얘기했듯이 메모리를 해제하더라도 이는 힙 관리자에서 해당 메모리를 free list에 추가할 뿐 메모리 페이지 자체는 사용 가능해 접근하더라도 런타임에서 오류가 나지 않는다.

 

하지만 만약에 접근한다면 해당 공간은 다시 할당가능한 영역이기 때문에 재할당 받은 메모리, 힙 메타데이터를 오염시킬 수 있다.

 

이 포인터가 메모리를 건드려서 오류가 발생한다면 오히려 에러를 찾으면 되지만, 메모리를 오염시키고 이를 계속 사용하게 된다면 사용자의 데이터가 오염된 상태로 프로그램이 지속되는 끔찍한 상황을 맞을 수도 있다.

 

메모리 누수

메모리를 동적할당 받은 상태에서 더 이상 사용하지 않는 메모리를 free 하지 않는다면 힙 관리자는 해당 메모리를 아직 사용한다고 생각해 재사용하지 못하기 때문에, 이 메모리는 사용하지 않지만 그대로 남아있는 메모리 누수 현상이 발생하게 된다.

 

이러한 할당이 지속적으로 반복된다면 

1.잦은 Page Fault가 생겨 프로그램이 느려진다.

2.Out of Memory가 발생한다.

3.OS가 프로그램을 강제 종료 시킨다.

4.시스템 수준에서 자원이 고갈되면 블루스크린 등 심각한 문제가 생길 수 있다.

등의 문제가 생긴다.

 

메모리 누수가 실제로 일어나는지 보려면 vs 디버그 모드에서 메모리를 확인할 수 있을 것이고

실제 돌아가고 있는 프로그램에서는 작업관리자에서 커밋 크기가 계속 늘어나는지 확인할 수 있을 것이다. 


추후 더 많은 정보가 생기면 수정 필요

'C, C++ > C, C++ 잡지식' 카테고리의 다른 글

CreateThread와 _beginthreadex 간단하게 알아보기  (0) 2025.10.08
구조체?  (0) 2025.06.14
C++ 캐스팅 연산자  (0) 2025.06.14
가상 함수 virtual  (1) 2025.06.06
malloc과 new, free와 delete  (2) 2025.05.31