LALA's blog

[ C 언어 ] 정적 메모리, 자동 메모리, 자유 저장소와 동적할당 본문

개발/C 언어

[ C 언어 ] 정적 메모리, 자동 메모리, 자유 저장소와 동적할당

lala.seeun 2020. 2. 12. 19:56

C 언어로 작성된 프로그램은 세 가지 종류의 메모리 영역을 가진다.

정적 메모리

프로그램이 실행하면서 프로그램에서 사용될 전역 변수/정적 변수를 메모리에 할당한 후 프로그램이 종료될 때 해제하는 영역이다. 따라서 잊어버리게 되더라도 큰 문제가 되지 않는다.

자동 메모리

자동 메모리는 스택 구로졸 이루어져 있다. 이곳에 저장된 변수는 코드 블록('{'와 '}'의 괄호로 이루어진 블록)이 종료됨에 따라 4차원의 세계로 사라진다. 

{ /* 코드 블록 시작 */
    int a = 43;
    double b = 1.1;
} /* 코드 블록 끝. 여기에서 a와 b는 자동 메모리에서 제거된다.*/
int Plus(int a, int b)  /* a와 b도 자동 메모리에 저장 */
{
    int c = a + b;      /* c도 자동 메모리에 저장 */
    return c;
} /* a, b, c 모두 자동 메모리에서 제거된다. */

위와 같은 코드 블록 안에서 선언된 변수들은 선언 당시에 자동 메모리에 저장되었다가 코드 블록의 끝에서 모두 제거된다.

자유 저장소

자동 메모리와는 달리 프로그래머가 직접 메모리를 관리하는 메모리 영역이다. 따라서 프로그래머는 자유롭게 메모리를 할당해서 사용하고, 그 메모리를 안전하게 해제해야 한다.

 

링크드 리스트의 노드 생성을 예시로 자동 메모리와 자유 저장소의 차이를 살펴보자.

1. 자동 메모리에 노드를 생성한 경우

Node* CreateNode(int NewData)
{
    Node NewNode;       /* 자동 메모리에 새로운 노드 생성 */
    
    NewNode.Data = NewData;
    NewNode.NextNode = NULL;
    
    return &NewNode;    /* NewNode가 생성된 메모리의 주소를 반환 */
} /* 함수가 종료되면서 NewNode는 자동 메모리에서 제거된다. */

함수 안에서 생성된 NewNode는 함수가 종료하면서 자동 메모리에서 제거된다. 하지만 CreateNode() 함수는 NewNode가 '존재했던' 메모리의 주소를 반환하기 때문에 문제가 발생한다.

 

2. 자유 저장소에 노드를 생성한 경우

자유 저장소에 메모리를 할당하려면 malloc() 함수가 필요하다.

void* malloc(size_t size);

malloc() 함수의 반환형인 void*는 만능 포인터이다. 어떤 자료형이라도 가리킬 수 있다. 다시 말해서 malloc() 함수가 할당한 자유 저장소의 메모리 주소를 어떤 형의 포인터로도 가리킬 수 있다. 

Node* NewNode = (Node*)malloc(sizeof(Node));

여기서 malloc() 함수는 sizeof 연산자가 측정한 노드의 크기만큼 자유 저장소에 할당하고 그 메모리 주소 값을 반환한다.

Node* CreateNode(int NewData)
{
    Node* NewNode = (Node*)malloc(sizeof(Node));
    
    NewNode->Data = NewData;
    NewNode->NextNode = NULL;
    
    return NewNode;
}

이처럼 수정하면 자유 저장소에 할당되어 정상적으로 노드가 생성된다.

 

자유 저장소에 메모리를 해제하려면 free() 함수가 필요하다.

void free(void *memblock);

해제하려는 메모리의 주소만 정확히 알려주면 free() 함수가 해결해준다.

 

 

 

[참고] 뇌를 자극하는 알고리즘