C 기준

  1. 지역 변수로 선언된 배열 - 함수 내에서 선언된 배열은 스택(stack) 영역에 할당됩니다. 배열의 크기는 컴파일 시점에 정해져 있어야 하지만, 실제 메모리에 대한 할당은 해당 지역 변수가 스코프에 들어갈 때 실행 시점(runtime 단계)에 이루어 집니다.

    #include <stdio.h>
    
    int main() {
        int arr[5]; // 함수내에서 선언된 배열 - 스택 영역에 할당
    
  2. 전역 변수나 정적 변수로 선언된 배열 - 전역 변수로 선언되거나 static 키워드를 사용하여 선언된 배열은 컴파일 단계에서 데이터(data) 영역에 할당됩니다. 이 영역의 변수들은 프로그램 시작부터 종료될 때까지 메모리에 남아있습니다.

    #include <stdio.h>
    
    int array[5]; // 전역 변수 - 데이터 영역에 할당
    
    void function() {
        static int array[5]; // static - 데이터 영역에 할당
    }
    
    int main() {
        function();
        return 0;
    }
    
  3. 동적 메모리 할당을 사용한 배열 - malloc, calloc 등의 함수를 사용하여 동적으로 할당된 메모리는 런타임 단계에서 힙(heap) 영역에 위치하게 됩니다. 이 영역의 메모리는 개발자가 직접 free 함수를 사용하여 해제해야 합니다.

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        int* arr = (int*)malloc(5 * sizeof(int)); // 힙에 배열 메모리 할당
    

JAVA 기준

따라서 C언어 기준으로 보면 array는 compile 단계에서 stack영역에 할당됩니다. 다만 JAVA를 기준으로 보면 array는 runtime 단계에서 heap영역에 할당됩니다. (JAVA에서 객체는 항상 heap영역에 할당되는데, JAVA에서 array는 객체이기 때문입니다)

추가적으로 교수님 답변

'할당'의 사전적인 의미는 몫을 갈라 나누는 것. 또는, 그 몫. 순화어는 `배정'. 이렇게 나와있군요. 메모리를 사용하기 위해서 나누는 것, 또는 따로 떼어놓는 것을 우리가 메모리 할당이라고 부릅니다. 저는 가끔 땅따먹기에 비유를 하곤하는데, '메모리에 금을 그어놓고, 여기는 내가 쓸 공간이니 건드리지 마.' 이렇게 선언하는 것이 할당이죠.

메모리에 뭔가를 저장하는 것을 할당한다고 표현하는 경우가 있는데, 보통은 저장하는 것과 할당하는 것을 혼동해서 그렇게들 부르는 것 같네요.

가상 메모리와 관련해서- 주소 공간의 일부를 특정한 용도로 사용하기 위해서 할당 하는 경우를 보통 우리가 메모리 할당이라고 부릅니다. 위에서 메모리라고 부르는 것이 일반 사용자 프로세스 (실행 중인 프로그램)에서는 주소공간이 되고, 프로그램이 사용할 수 있는 전체 메모리 주소는 가상메모리 상의 주소 공간이 됩니다. (알고 있겠지만..) 흔히들 메모리 할당이라고 하면, 이러한 주소 공간 중에서 그 일부를 할당 (일정 영역을 코드/변수 등의 사용을 위해서 예약하는 것) 하는 작업을 말하는 것이죠.

대개 메모리 할당이라고 하면 특정 변수를 위한 메모리 영역을 예약해 두는 것을 얘기하는 경우가 많은데, 꼭 변수에 대해서만 할당을 하는 것은 아니고, 코드 영역이나 데이터 영역, 스택 영역에 대해서도 할당을 합니다. (운영체제 내부에서 하는 일입니다.) 그런데, 대개의 경우에 컴파일 타임에 많은 것들이 결정 가능하지요. 예를 들면, 컴파일된 실행 파일이 윈도에서 실행될지, 리눅스에서 실행될지, 어떤 CPU를 대상으로 하는지 등등. 컴파일러에서 이러한 목적 실행환경을 '타겟 플랫폼'이라고 하는데, 타겟 플랫폼이 지정한 가상메모리 주소공간의 형태에 따라서 코드는 주소 공간의 어느 영역에, 데이터는 어느 영역에, 스택은 어느 영역에 들어갈 것인지 결정됩니다. 이처럼 컴파일하는 시점에 주소 공간이 할당되기도 하고요, 이러한 메모리 할당을 컴파일 타임에 메모리가 할당된다고 표현합니다.

스택에 변수를 할당한다고 하고, 이 변수는 컴파일 타임에 할당된다는 표현은 해석하면 다음과 같은 내용이죠. C에서 지역변수를 선언하게 되면, 그 지역 변수는 해당 함수의 실행동안만 유효한 값을 가지게 되죠. 그래서, 스택 영역에 변수가 들어갈 주소들을 미리 떼어 놓는 것이죠. 이 공간은 컴파일할 때 결정이 되죠. 스택의 top은 실행시에 변경이 되지만, 그로부터 상대적인 위치로 지역 변수가 사용할 주소가 결정 가능하니까요.

반대로, malloc을 사용하는 경우는 힙 영역에 주소를 할당하기도 하는데, 대개 프로그램을 실행하면서 그 때 그 때 필요한 메모리 크기가 다른 경우 사용자가 필요한 메모리 용량만큼씩 주소 공간을 할당하는 것을 두고, 동적으로 메모리를 할당한다고 표현합니다. 그런데, 동적 메모리 할당은 그 특성 상, 실행 하면서 요청하는 크기가 변경되기 때문에, 실행 중에 메모리 할당을 할 수 밖에 없죠. 그래서, 동적 메모리 할당은 런타임 메모리 할당이 될 수 밖에 없습니다.

참고로, 물리 메모리도 할당을 합니다. (운영체제 내부에서 하는 일입니다.)