Qaupot Blog
Software Engineering, Trip

413. 동적 메모리 할당

🕐 Sun, 09 Feb 2014 09:00:00 GMT 🕓 Tue, 24 Aug 2021 08:43:00 GMT

메모리 동적 할당

"스택" 세그먼트 공간에 메모리를 할당 하는 방법인 지역변수들을 사용했었습니다.
지역변수들은 함수가 호출될때마다 새롭게 생겨나기에, 별도의 관리가 필요없는 장점이 있지만 자료의 형태, 자료의 크기를 미리 예상하여 할당을 해 두어야 합니다.

99%의 확률로 3 ~ 4byte 만 사용하지만, 1% 확률로 10000byte 가 필요하다고 하면,
어쩔 수 없이 10000byte 를 변수(배열)로 선언해 두어야 합니다. 이는 매우 불합리하며 비 효율적인 상황입니다.

따라서, 프로그램의 런타임(동작중)에 메모리를 할당하고 사용할 수 있는 방법이 필요했고, 이를 "동적 메모리 할당"이라고 합니다.

메모리 동적 할당 개념과 함수

"힙" 세그먼트 공간에 원하는 만큼 공간을 할당한 다음, 그 첫 메모리 주소를 돌려줍니다.

여러 세그먼트로 나뉘어 있더라도 결국은 가상 메모리 4GB(32bit 기준)안의 어느 한 지점입니다.
따라서 언제든지 메모리 주소로 표현 및 접근 할 수 있습니다.

#include <stdio.h>
#include <stdlib.h>

int main(int argc,char** argv)
{
    int SizeN = 10;
    int* intPtr = (int*)malloc(sizeof(int) * SizeN);

    intPtr[0] = 1;
    intPtr[1] = 3;

    printf("%d %d",intPtr[0],intPtr[1]);

    free(intPtr);

    return 0;
}

동적으로 메모리를 할당 및 해제 하기 위해 malloc 함수와 free 함수를 사용 했습니다.

  • stdlib.h를 include 하면 이 함수를 찾을 수 있습니다.

malloc

malloc 은 메모리를 할당하는 함수입니다. 인수는 할당할 byte 의 수 이며 리턴값은 할당한 메모리의 포인터 입니다.
리턴 값은 void* 형으로 들어오게 되는데, 이는 어떠한 자료형의 메모리 주소값이라도 표기 할 수 있기 때문입니다.

정확히는 malloc 는 자료형을 전혀 신경쓰지 않으며 해당한 byte 의 크기만큼을 할당해서 돌려줍니다. 이 byte 뭉치를 어떻게 나누어 쓰는지에 대해서는 전적으로 프로그래머의 몫입니다.

int* intPtr = (int*)malloc(sizeof(int) * SizeN);

sizeof 연산자는 해당하는 자료형의 크기를 알 수 있습니다.

  • sizeof 는 함수처럼 생겼지만 함수가 아니라 연산자입니다. 확인하려면 어떠한 헤더파일도 include 하지 않고 sizeof 를 호출해 보세요.
  • sizeof(int)는 int 형의 크기인 4byte 를 돌려줄 것입니다.

SizeN 변수에 10을 넣었으므로, malloc 함수는 최종적으로 40 byte 의 메모리 뭉치를 돌려줄 것입니다.
이 메모리 주소는 void*로 들어오므로, (int*) 캐스팅을 통해 int 형 포인터에 대입시켰습니다.

결론적으로 int intPtr[10]; 을 선언한것과 동일한 효과를 얻은 것입니다.

  • 전자는 힙, 후자는 스택 세그먼트입니다.

free

free 는 메모리 할당을 해제하는 함수입니다
스택에 생성된 메모리와는 다르게 malloc 로 할당한 메모리는, 프로그램이 종료될 때까지 자동으로 해제되지 않습니다.
따라서 해당 메모리가 불필요해 지게 된다면, free 로 해제해 주어야 합니다.

new / delete (C++)

C++ 에서는 new 혹은 delete 키워드 힙에 메모리 할당을 할 수 있습니다. 이 키워드는 class 를 위한 키워드 이지만, 다른 자료형에도 사용할 수 있습니다.

다만, malloc / free 와 new / delete 를 혼용하지 않아야 합니다.

new / delete 는 class 의 생성자와 소멸자를 호출시키는 기능을 가지고 있기 때문에, malloc 으로 할당한 힙 메모리를 delete 로 삭제하는 등의 케이스에서 문제를 발생시킬 수 있습니다.

이 블로그는 개인 블로그입니다. 게시글은 오류를 포함하고 있을 수 있지만, 저자는 오류를 해결하기 위해 노력하고 있습니다.
게시글에 별도의 고지가 없는 경우, 크리에이티브 커먼즈 저작자표시-비영리-변경금지 4.0 라이선스를 따릅니다.

This blog is personal blog. published posts may contain some errors, but author doing efforts to clear errors.
If post have not notice of license, it under creative commons Attribution-NonCommercial-NoDerivatives 4.0.