간혹 스택과 힙의 차이를 이렇게 이해하는 경우가 있음.
스택 == 크기 불변, 메모리 주소상 연속적
힙 == 크기 변화 자유로움, 메모리 주소상 비연속적
이 오해는 좀 더 나아가면 C에서 포인터가 중요한 이유는 힙에서 대규모 메모리를 자유롭게 할당받아 사용할 수 있게 해주기 때문이라 생각하기까지 하게 됨. 그렇게 사용할 수 있는 것은 사실이고 많은 사람들이 그렇게 사용하는 것도 사실이지만, 그건 좀 핀트가 어긋난 이해라 할 수 있음.
왜냐면 스택도 런타임 와중 크기가 분명 변하며 심지어 많은 OS에서 그 최대크기를 무제한으로 설정할 수 있기 때문임. 그리고 그 과정에서 당연하지만 데이터는 '물리적' 주소 상으로 볼 시 비연속적으로 저장되게 됨. 리눅스의 경우에는 그냥 ulimit -s unlimited 를 입력하면 되니까 그리 어려운 것도 아님. 힙에는 별거 없는데 스택이 10gb인 프로세스도 얼마든지 존재할 수 있는거지.
여담이지만 그렇기에 흔히 C에서 배열의 길이는 상수로밖에 정할 수 없고 그것은 스택의 길이가 compile-time에 constant해야하기에 그렇다라고 듣는 말 역시 구라임. 실제로는 C99 스탠다드에 이미 VLA(variable-length array)라고 변수값으로 배열의 길이를 선언할 수 있는 기능이 포함되어 있음. 보통 스택 오버플로우 에러 뜨기 쉬워 컴파일러들이 이 기능 끌 수 있는 옵션을 넣고 그게 디폴트 옵션이라 모를 뿐이지.
내 생각에 스택과 힙의 차이는 이렇게 보는게 더 맞다고 본다.
스택 == 변수 그리고 따라서 메모리 자원의 획득, 놓아주기 및 참조가 지역적으로 이루어짐.
힙 == 변수 그리고 따라서 메모리 자원의 획득, 놓아주기 및 참조가 프로그래머 꼴리는대로 이루어짐.
여담이지만 스택의 크기가 어떻게 무제한적으로 불어나게 할 수 있는지 그 원리가 궁금하면 MMU(memory management unit), 그리고 가상 메모리 공간(virtual memory space)과 물리적 메모리 공간(physical memory space)에 대해 알아보고 그 후 리눅스/윈도우즈에서는 각 프로세스마다 독자적이고 서로 다른 개별적 가상 메모리 공간을 하나씩 할당한다는 것을 곱씹어보면 쉬움.
댓글 0