나만의 작은 도서관

[C++] 동적 할당 본문

C++/문법 및 메소드(STL)

[C++] 동적 할당

pledge24 2025. 3. 19. 23:03

동적 할당이란?

  • 크기가 가변적으로 변할 수 있는 메모리, 즉, 동적 메모리를 할당하는 것을 의미한다.
  • C++에서는 malloc-free, new-delete을 이용해서 동적 할당을 할 수 있다.
  • 할당 시, 메모리는 힙(heap) 영역에 위치한다.

malloc-free 방식

  • C 스타일의 동적 할당 방식. 기존의 C는 힙 영역을 활용하지 않았지만, 시대의 요구에 따라 힙(heap) 상에서의 메모리 할당을 지원하기 위해 생겼다.
  • malloc: 힙에 메모리를 할당하는 “함수”
    • 넣어준 값만큼 메모리를 할당한다. (바이트 단위)
    • 메모리 할당 성공 시, 시작 주소를 가리키는 void 타입 포인터를 반환한다.
    • 메모리 할당을 실패했다면(ex. 메모리 부족) null을 반환한다.
  • free: 힙에 할당한 메모리를 해제하는 “함수”
    • 넣어준 식별자(ex. 변수 이름) 할당된 메모리를 해제한다.
    • free는 메모리 크기 지정 없이 해제할 수 있다는 특징이 있는데, 이는 할당할 때 추가한 헤더 영역이 메모리 크기 데이터를 저장하고 있기 때문에 가능하다.

 

malloc-free 사용법

  • T* pointer: T 타입의 포인터 선언.
  • (T*) malloc(sizeof(T)): T 타입의 크기만큼 힙에 공간을 할당하고, T 타입의 포인터로 캐스팅.
// 동적 메모리 할당
T* pointer = (T*)malloc(sizeof(T)); 

free(pointer) // 할당한 메모리를 해제(free)

 

malloc-free 배열

  • 배열을 할당하고 싶다면 이중 포인터(다중 포인터)를 사용한다.
  • 이중 포인터로 malloc을 사용했다면, 반복문을 통해 하나씩 free 해야 한다.
// 동적 배열의 메모리를 할당
T** arr = (T**)malloc(sizeof(T*) * N);

for(int i = 0; i < N; i++){
    arr[i] = (T*)malloc(sizeof(T) * N);
}

// 할당한 동적 배열을 해제(free)
for(int i = 0; i < N; i++){
    free(arr[i]);
}
free(arr);

 


new-delete 방식

  • C++스타일의 동적 할당 방식.
  • malloc-free가 함수인 것과 달리 new-delete는 연산자이다.
  • 타입이 클래스인 경우 new-delete는 각각 생성자와 소멸자를 호출한다.
  • delete는 new로 할당한 메모리만 해제할 수 있다.

 

new-delete 사용법

  • T* pointer: T 타입의 포인터 선언
  • new T: T 타입의 크기만큼 힙에 공간을 할당.
// 동적 메모리 할당
T* pointer = new T;
T* pointer = new T(value); // 초기화도 동시에 할 수 있다.

delete p // 할당한 동적 메모리를 해제(free)

 

new-delete 배열

  • 배열을 할당하고 싶다면 new []를 사용해야 한다.
  • new []로 할당 시 delete []를 통해서 해제해야 한다.
// 동적 배열의 메모리를 할당
T* pointer = new T[size];

delete[] pointer; // 할당한 동적 배열을 해제(free)

 

new-delete 사용 예제

int *pointer; // nullptr 또는 NULL
pointer = new int;
*pointer = 21;
    
char *pArr = NULL;
int size = 10;
pArr= new char [size];
delete[] pGrades;

 


malloc-free vs new-delete

  • malloc-free는 함수, new-delete는 연산자다.
  • 일반적인 상황에서는 new-delete를 사용하는 것이 편리하지만, 타입에 상관없이 특정 크기의 메모리를 할당하고 싶은 경우에는 malloc-free 방식을 사용한다.

알아둬야 할 점

메모리 누수(memory leak)

  • 메모리 누수사용하지 않는 메모리가 계속 공간을 차지하는 현상으로, 할당한 메모리를 제대로 해제(free) 하지 않았을 경우 발생한다.
    • ⇒ 공원에 돗자리를 깔아놓고 그대로 집에 가버리는 것과 같은 현상
  • 메모리 누수는 동적 메모리 공간에서 자주 발생하며, malloc 또는 new를 통해 동적 할당을 한 뒤, free, delete가 제대로 이루어지지 않는 경우가 주원인이다.
  • 따라서, malloc-free, new-delete는 항상 하나의 쌍으로 간주하고 사용해야 한다.

double free(또는 double delete)

  • 더블 프리(double free)같은 메모리를 두 번 연달아 해제(free)하는 행위를 말한다.
  • 더블 프리할 경우, 이미 헤더 영역의 정보가 날아갔기 때문에 해제해야 할 메모리 크기를 알 수 없어 크래시가 발생한다.

Use After Free

  • Use After Free(줄여서 UAF)해제된 메모리의 데이터를 사용하는 행위를 말한다.
  • Use After Free 또한 동적 메모리에서 발생하며, 아래와 같은 경우가 원인이 된다.
    • 해제된 메모리를 가리키는 포인터(댕글링 포인터)를 사용하는 경우
    • “동적 메모리는 같은 메모리를 여러 번 재할당한다”는 특성에 의해 [메모리 해제 → 할당] 순서에서, 해제된 메모리를 재할당받아 아직 지워지지 않은 이전 데이터에 접근하는 경우
  • Use After Free는 메모리 오염(Memory Corruption)을 일으킬 수 있으므로 항상 조심해야 한다!

 

참고 자료

https://modoocode.com/169

https://modoocode.com/98

https://shayete.tistory.com/entry/7-Use-After-Free

https://encyclopedia.kaspersky.com/glossary/use-after-free/