<aside> <img src="/icons/list_gray.svg" alt="/icons/list_gray.svg" width="40px" />
목차
</aside>
동적 할당을 위해서 위와 같이 메모리 구조와 힙(Heap) 영역을 알아보았다. 동적 할당은 프로그램 실행 중에 필요한 만큼의 메모리를 할당하고 해제할 수 있는 기능이다. C++에서는 주로 malloc/free와 new/delete를 사용하여 동적 메모리를 관리한다.
| 정적 할당 | 동적 할당 | |
|---|---|---|
| 메모리 영역 | 스택(Stack) | 힙(Heap) |
| 할당 시점 | 컴파일 시점 | 런타임 시점 |
| 메모리 크기 | 고정 | 유동적 |
| 관리 방식 | 자동 | 수동(직접 해제 필요) |
| 장점 | 빠른 접근 속도, 안전 | 메모리 효율적 사용, 유연성 |
| 단점 | 크기 변경 불가, 메모리 낭비 가능 | 메모리 누수 위험, 관리 필요 |
먼저 C 스타일의 메모리 할당 방식인 malloc을 살펴보자.
class Monster
{
public:
int _hp;
int _x;
int _y;
};
int main()
{
void* ptr = malloc(1000);
**Monster* m1 = (Monster*)ptr;**
m1->_hp = 100;
m1->_x = 1;
m1->_y = 1;
}
위 코드에서 void* ptr = malloc(1000)은 1000바이트의 메모리를 힙에 할당하고, 그 시작 주소를 ptr에 저장한다. 이후 Monster* m1 = (Monster*)ptr과 같이 Monster 타입으로 캐스팅하여 실제 Monster 객체처럼 사용할 수 있다.
malloc()
void* 형태로 반환한다.nullptr**를 반환한다.malloc() - 실험
Monster* m1 = (Monster*)ptr 코드 줄에 중단점을 놓고, 디버그 모드로 실행한다.
ptr을 검색하여 메모리에 어떻게 저장되어 있는지 확인한다.
위 메모리 뷰에서 볼 수 있듯이, malloc()으로 할당한 메모리는 초기화되지 않은 상태로 임의의 값들을 포함하고 있다.
ptr을 통해 값을 대입하면 다음과 같은 과정으로 진행된다.

위 메모리 뷰에서 볼 수 있듯이, 메모리에 값을 직접 대입하면서 Monster 객체의 각 멤버 변수(_hp, _x, _y)가 순차적으로 저장되는 것을 확인할 수 있다.
free()
free() - 실험

위 메모리 뷰에서 볼 수 있듯이, **free()**로 메모리를 해제한 후, 메모리가 0xDD 패턴으로 채워진 것을 확인할 수 있다.
class Monster
{
public:
int _hp;
int _x;
int _y;
};
int main()
{
**Monster* m1 = new Monster[5];**
m1->_hp = 100;
m1->_x = 1;
m1->_y = 1;
delete m1;
}
new
new 연산자는 지정된 타입의 객체를 위한 메모리를 힙에 할당하고, 해당 객체의 생성자를 자동으로 호출한다.new Type[size], 만약 할당 실패 시 예외std::bad_alloc를 던진다.delete 연산자를 사용하여 해제해야 하며, 배열로 할당한 경우 delete[] 를 사용해야 한다.new - 실험
마찬가지로 중단점을 설정한 후, 디버그 모드에서 m1을 메모리 뷰에 검색해보면?

위 메모리 뷰에서 볼 수 있듯이, new로 할당된 메모리는 malloc()과 달리 0x3C와 같은 특별한 패턴으로 초기화되어 있다.
왜 이런 값이 들어있냐 하면, C++의 new 연산자가 메모리를 할당할 때 자동으로 초기화를 수행하기 때문이다. 이러한 초기화는 디버깅 시 할당된 메모리를 쉽게 식별할 수 있게 해주며, 미초기화 메모리 사용으로 인한 문제를 방지하는 데 도움을 준다.

malloc()과 동일하게도, 메모리에 값을 직접 대입하면서 Monster 객체의 각 멤버 변수(_hp, _x, _y)가 순차적으로 저장되는 것을 확인할 수 있다.
delete

delete도 마찬가지로, free()와 동일하게 메모리를 해제한 후, 메모리가 0xDD 패턴으로 채워진 것을 확인할 수 있다.
| 특징 | malloc/free | new/delete |
|---|---|---|
| 언어 | C 스타일 | C++ 스타일 |
| 타입 | 함수 | 연산자 |
| 반환 형식 | void* (타입 캐스팅 필요) | 객체 타입의 포인터 |
| 메모리 크기 지정 | 바이트 단위로 직접 지정 | 컴파일러가 자동 계산 |
| 생성자/소멸자 | 호출하지 않음 | 자동으로 호출 |
| 배열 할당 | 크기 계산 필요 | new[] / delete[] 사용 |
| 실패 시 | NULL 반환 | 예외 발생 |
| 초기화 | 수동으로 해야 함 | 자동으로 초기화 |
new/delete가 더 유리하다. 타입 크기를 자동으로 계산해주고, 객체의 생성자/소멸자도 알아서 호출해주기 때문이다.malloc()/free()는 바이트 단위로 원하는 크기만큼 메모리를 할당할 수 있어서, 타입에 구애받지 않고 유연하게 메모리를 다룰 수 있다는 장점이 있다.