[cs, c++]개발자 99%가 모르는 스택과 힙 영역에 관한 진실
과연 스택오버플로우란 무엇인가
스택이 너무 커져서 힙 영역을 침범한다?
처음 프로그래밍을 배울 당시에는 스택과 힙 영역은 서로 같은 공간을 쓰고,
스택은 높은 주소에서 낮은 주소로, 힙은 낮은 주소에서 높은 주소로 메모리 공간을 차지한다고 배웠다.
그리고, 스택이 차지하는 공간이 힙 영역을 침범하는 순간 스택오버플로우가 발생하며,
반대의 경우에는 힙 버퍼 오버플로우 라고 알고있었다.
하지만 많은 리서치 끝에 이 내용은 틀린 내용임을 알아냈다. 정말 많은 리서치를 하였다.
스택과 힙의 그림
많은 개발 블로그에서 아래쪽에 스택을 표현하고 위쪽에 힙을 그려넣는 경우가 많다.
이유로 보았을때, 스택이 쌓이는 형태로 구성되어 있기에 그렇게 표현되는 것 같은데
사실은 스택이 위에 있고 힙이 아래에 있는 식의 구조가 더 합리적이다.
혼동을 줄 수 있는 이미지
직관적으로 표현된 이미지
영어로 된 자료들을 검색하면 스택이 위에 있는 자료를 더 많이 볼 수 있을것이다.
앞서 언급했듯이 스택은 높은 메모리 주소부터 사용하기 때문이다.
그림을 보고 스택이 낮은 메모리 주소로 착각하는 경우가 많기에 짚고 넘어가고 싶다.
스택오버플로우란
그렇다면 과연 진실은 무엇이었을까?
페이징 기법만 살펴보아도 사실 주니어 개발자라면
스택오버플로우에 대한 의구심이 들어야 정상이라고 생각한다.
스택오버플로우는 너무 커진 스택이 스택 주소공간을 침범하는 문제이며, 힙 영역과는 직접적인 연관성이 없다.
우리가 알고 있는 힙 영역을 침범하는 경우는 힙 버퍼 오버런 또는 힙 버퍼 오버플로우 라고 부른다.
따라서, 스택 오버플로우와 힙 오버플로우는 서로 다른 문제이며, 각각의 문제 상황에서 발생 가능한 영역이 다르다.
버퍼
스택 영역은 스택 프레임의 크기에 따라서 적절하게 조정된다.
스택 오버플로우의 반대격인 힙 메모리의 오버플로우는 힙 버퍼 오버플로우 라고 부른다.
명칭부터가 버퍼라는 단어가 들어가는 것을 보면 분명 버퍼와 관련이 있다는 사실을 알 수 있다
사실 스택 오버플로우도 스택 버퍼를 초과해서 값을 저장했기 때문에
인접한 메모리 공간을 침범하게 되는 것이다.
여기서 인접한 메모리 공간은 물론 힙 영역이 될 수도 있지만, (연속적인 할당을 하기 때문에),
100에 99는 다른 함수의 스택 프레임으로, 드물게 전역 변수 등의 데이터 공간으로 침범할 수 있다는 소리다.
이는 대부분의 시스템에서 스택 메모리의 끝에서 접근하지 못하도록 설정되어 있기 때문에,
그러한 일이 일어나면 정상적인 상황이 아닌 것이다.
마치며
사실 운영체제에 따라서 스택과 힙의 주소공간이 처음부터 겹칠 수도 있는것은 사실이다.
다만, 지금 시중에 나와있는 컴퓨터 중에서는 특수목적 디바이스를 제외하고는 없다고 보는것이 타당하다.
하지만 과거에는 그 빈도수가 높았던 반면, (처음 설계될 당시의 기술력 부족)
23년 기준 운영체제에서는 매우, 매우 드문 경우라고 장담한다.
특히 최신 기술을 항상 업데이트 해야하는 게임 업계의 경우에는
그런 구식 시스템 때문에 손해보는 일은 거의 없다고 봐야한다.
그렇기 때문에 사실상 버퍼를 제대로 관리하고 재귀함수 대신 스택을 이용하는 등의
메모리 관리 기술을 통하여 (그렇다고 또 항상 스택이 효율적인 것은 아니다) 문제를 예방하는 것이 중요하다.
또 다른 경우에는 재귀나 스택으로는 크기가 감당이 되질 않아서
오버헤드가 조금 높더라도 반복문으로 처리해야 되는 경우도 있다.
개발자는 하드웨어적인 부분도 이해를 하고 있어야 더 효율적인 개발을 할 수 있는것은 확실하다.
다른 블로그 등에서 설명하는 영역 침범은 용어와 정보의 혼동으로 보인다.
처음에 그렇게 배운 사람이 다른 사람에게 그 정보를 전달하고, 그것이 잘못된 정보인지 의심하지 않는다면
충분히 이러한 일이 생길 것이라고 생각한다.
사실 그만큼 중요한 사항은 아닐 수 있다. (실무에서는 ‘왜’ 보다는 ‘그래서 어떻게’ 가 더 중요하기 때문에)
하지만 대부분의 면접 질문에서 이런 기초적인 부분에 대한 질문을 하는 경우가 많기 때문에,
면접관의 입장에서도 잘못 알고 있는 경우가 많을 것 같다.
정말 중요한 정보글이기 때문에, 관련 출처를 모두 남기겠다.
-
https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap
-
https://stackoverflow.com/questions/5836309/stack-memory-vs-heap-memory
-
https://vickieli.medium.com/binary-exploitation-buffer-overflows-a9dc63e8b546
-
https://www.geeksforgeeks.org/stack-vs-heap-memory-allocation/
참고한 문헌
댓글 남기기