포스트

동적 할당 키워드 (new, malloc, calloc, realloc, virtualAlloc)

동적 할당 (Dynamic Allocation)

동적 할당프로그램 실행 중에 필요한 메모리 공간을 할당하는 프로그래밍 기법입니다.

정적 할당과 달리, 동적 할당은 실행 시간에 메모리의 크기와 위치를 결정하므로 더 유연하게 메모리를 관리할 수 있습니다.

동적 할당의 주요 장점은 메모리의 효율적인 사용입니다. 필요한 만큼의 메모리를 할당하고 해제할 수 있으므로, 불필요한 메모리 낭비를 줄일 수 있습니다.
이때, 동적으로 할당된 메모리는 힙(heap) 영역에 저장됩니다.

C++에서는 malloc, calloc, realloc, new 등의 함수를 사용하여 동적 할당을 수행할 수 있으며, 할당된 메모리는 free 또는 delete로 해제해야 합니다.


malloc

  • 메모리의 힙 영역에 바이트 단위로 할당하고, 할당된 메모리의 시작 주소를 반환합니다.
  • 할당된 메모리는 초기화 되지 않은 상태입니다.
  • 메모리 해제는 free
1
malloc(원하는 크기)
1
2
3
4
5
6
7
8
#include <stdlib.h>

int main() 
{
    int* arr = (int*)malloc(10 * sizeof(int)); // 10개의 int 크기만큼 메모리 할당
    //...
    free(arr); // 메모리 해제
}

calloc

  • malloc과 마찬가지로 힙 영역에 바이트 단위로 할당하고, 할당된 메모리의 시작 주소를 반환합니다.
  • 할당을 원하는 메모리 크기를 자료형의 크기개수 두 개의 인자로 받습니다.
  • 0으로 초기화 해줍니다. (초기화 과정이 포함되므로 malloc 보다는 느릴 수 있습니다.)
  • 메모리 해제는 free
1
calloc(원하는 개수, 원하는 크기)
1
2
3
4
5
6
7
8
#include <stdlib.h>

int main() 
{
    int* arr = (int*)calloc(10, sizeof(int)); // 10개의 int 크기만큼 메모리 할당
    //...
    free(arr); // 메모리 해제
}

realloc

  • 이미 할당된 메모리의 크기를 바꾸어 재할당할 때 사용합니다. 이때, 크기가 변경된 메모리의 시작 주소를 반환합니다. (메모리 재할당시 메모리 주소가 변경될 수 있습니다.)
  • 재할당 받고 싶은 메모리 주소크기를 인자로 받습니다.
  • 메모리를 재할당 받을 위치에 충분한 공간이 있다면 바로 이어서 추가 메모리 공간을 할당해주고, 충분하지 않다면 새로운 공간을 할당해줍니다.
  • 따라서 크기 변경 과정에서 메모리 복사가 일어날 수 있으므로 비효율적일 수 있습니다.
1
realloc(메모리 주소, 원하는 메모리 크기)
1
2
3
4
5
6
7
8
9
10
#include <stdlib.h>

int main() 
{
    int* arr = (int*)malloc(5 * sizeof(int)); // 5개의 int 크기만큼 메모리 할당
    //...
    arr = (int*)realloc(arr, 10 * sizeof(int)); // 메모리 크기 재조정 (10개의 int 크기로 확장)
    //...
    free(arr); // 메모리 해제
}

new

  • 힙 영역의 메모리를 자료형 단위로 할당합니다. (클래스 단위도 포함한 자료형 단위)
  • 새로 메모리를 할당할 때, 생성자를 호출하므로 초기화 과정이 자동으로 이루어집니다.
  • 메모리 해제는 delete
1
new 자료형
1
2
3
4
5
6
int main()
{
    int* num = new int; // int 타입의 동적 객체 생성
    //...
    delete num; // 객체 해제
}

virtualAlloc

  • Windows 운영체제에서 가상 메모리(Virtual Memory)에 공간을 할당하고 관리합니다.
  • 페이지 단위로 메모리를 할당할 수 있으며, 특정 주소에 메모리를 할당할 수 있습니다. (보통 예약된 페이지가 아니라면 NULL로 넘겨 비어있는 충분한 공간을 할당 받습니다.)
  • 연속적으로 메모리를 할당하고 해제하는 과정에서 발생하는 메모리 단편화를 극복할 수 있습니다.
  • 대용량의 메모리가 필요한 경우 유용합니다.
  • 메모리에 대한 예약이 가능하고, 예약 상태 및 엑세스 권한 지정이 가능합니다.
  • 메모리 예약 플래그는 다음과 같습니다.
    • MEM_COMMIT: 물리 메모리를 할당하고 페이지가 물리 메모리에 매핑되며, 초기 값은 0이 됩니다.
    • MEM_RESERVE: 가상 주소 공간을 예약하지만 물리 메모리를 할당하지 않습니다.
      따라서, MEM_RESERVE만 사용하면 해당 페이지에 액세스할 수 없으며, MEM_COMMIT을 사용해야 페이지에 액세스할 수 있습니다.
  • 엑세스 권한은 다음과 같습니다.
    • PAGE_NOACCESS: 페이지에 대한 모든 액세스를 차단합니다.
    • PAGE_READWRITE: 페이지에 대한 읽기 및 쓰기 액세스를 허용합니다.
    • PAGE_READONLY: 페이지에 대한 읽기 액세스만 허용합니다.
  • 메모리 해제는 virtualfree
1
VirtualAlloc(NULL(메모리 시작 지점), 4KB 단위의 크기, COMMIT 또는 RESERVE, 엑세스 권한)
1
2
3
4
5
6
7
#include <windows.h>

int main() {
    LPVOID pMemory = VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_READWRITE); // 4096 바이트 크기의 가상 메모리 할당
    //...
    VirtualFree(pMemory, 0, MEM_RELEASE); // 메모리 해제
}

참고

VirtualAlloc (가상 메모리 할당 및 예약)

이 기사는 저작권자의 CC BY-NC-ND 4.0 라이센스를 따릅니다.