인프런 커뮤니티 질문&답변

mir8725님의 프로필 이미지
mir8725

작성한 질문수

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part1: C# 기초 프로그래밍 입문

스택과 힙

클래스의 heap 할당

작성

·

512

0

스택과 달리, heap은 프로그램 실행 중간에 동적으로 할당되는 메모리 공간이라고 알고 있습니다.

질문1)
그렇다면 동적 할당이란 무엇인가요?
실행 도중에 동적으로 할당 받는다는게 어떤 경우이고
어떤 의미인지 잘 모르겠습니다

질문2)
클래스의 어떤 부분이 동적 할당이라는 건가요?
구조체와 똑같이 변수 할당하고 메소드도 있고 한데, 이유가 매우 궁금합니다.

답변 3

5

Rookiss님의 프로필 이미지
Rookiss
지식공유자

1)
동적(Dynamic)으로 할당된다는 의미는
[그때 그때 필요할 때 메모리를 할당 받아] 사용한다는 의미입니다.
(Ctrl Alt Del 작업 관리자에서 지금 프로그램들이 사용하고 있는 메모리를 볼 수 있죠)

예를 들면 어떤 MMORPG 게임에서
동접이 1명~100만명 사이라고 가정해봅시다.
처음에 게임이 실행되면, 메모리를 얼만큼 잡아야 할까요?
플레이어가 최대 100만 명 입장 가능하다고 해서
그 100만 명에 해당하는 메모리를 처음부터 할당하면,
실제로 그만큼 다 사용할 일도 거~의 없을텐데 낭비가 매우 심하겠죠.
그러니 처음부터 최대 메모리 만큼을 할당하는 방식이 아니라,
(동접자가 늘어남에 따라) 그때 그때 필요할 때 메모리를 할당 받아 차츰 늘려가면
이런 비효율성 문제를 해결할 수 있습니다.
참고로 스택 메모리는 처음부터 고정 크기만큼 할당하고 그 안에서만 재사용하는 방식입니다.
주로 함수가 호출 내역 (stack frame)을 관리하는 용도로 사용되고,
추가로 함수 내부에서 사용되는 struct 변수들의 메모리로도 임시적으로 사용됩니다.

2)
[어떤 부분이] 동적 할당 된다기 보다는
[class로 설계된 객체의 Instance를 만들면 무조건] 동적 할당이 됩니다.
즉 C#에서 class는 무조건 동적으로 할당되어, heap 메모리에 올라가게 됩니다.
C++과 명확하게 다른 점이죠.

----------------- 참고 ----------------

그런데 굳이 왜 이런 한계를 만들었을까? 이상할 수도 있지만
사실 이게 위험을 최소화하고 안전을 강화하기 위해서입니다.
C++에서는 struct이나 class이나 stack/heap 양쪽에 다 사용 가능하고,
개념적으로 둘 사이에 별 차이가 없습니다.
그런데 여기서 문제는 stack 주소를 참조(C++ 포인터)한다는 개념 자체가
매우 위험한 발상이라는 것입니다.
heap과 다르게 stack은 유효 범위가 계속 달라지는데
이미 사용하지 않는 영역에 대한 참조값을 계속 들고 있으면,
의도하지 않게 작은 실수에 의하여 메모리를 오염시키는 (엉뚱한 메모리의 값을 수정하는) 일이 발생할 수 있고
이게 정말 정말 C++의 가장 큰 무서움이기도 합니다.
정말 한 번이라도 메모리 깨지는 경험을 라이브에서 해보시면
두 번 다시 C++을 쳐다보기도 싫어질 수도 있습니다.
참고로 오염된 메모리는 그 자리에서 crash가 나지 않고
나비 효과가 신나게 굴러가다가 한~참 후에 엉뚱한 곳에서 crash 나는 경우가 많기 때문에
어디서 잘못 되었는지 찾기도 매우 힘들고
넓은 바다 해안가에서 잃어버린 반지를 찾는 느낌으로 버그를 찾아야 합니다.

3

Rookiss님의 프로필 이미지
Rookiss
지식공유자

음 그건 좀 미묘한데요.
class를 new 문법으로 생성할 때 그 새로운 객체가 힙 영역에 만들어지는 것은 맞고,
사실 stack/heap의 구분은 일반 변수나 객체만 해당합니다.

함수 같은 경우는 딱히 heap/stack 메모리에 할당하는 개념이 아닙니다.
매우 간단하게 요약하면 (언어마다 차이는 있지만)
기본적으로 우리가 코드를 짜고 Visual Studio를 이용해 컴파일을 하면,
컴퓨터가 이해할 수 있는 일련의 명령어들로 변환됩니다.
그리고 그 명령어들은 실행 파일 (Windows의 exe 파일)에 박혀 있는데
처음에 프로그램을 실행할 때 그 명령어들을
일단 메모리에 다 올리고 시작을 합니다.
그런데 그건 동적으로 할당되는 개념도 아니고 (heap X),
그렇다고 스택에 임시로 탑재되는 개념도 아니라서 (stack X)
stack/heap이 아닌 제 3의 영역 (code 영역)이라고 생각하시면 됩니다.

0

mir8725님의 프로필 이미지
mir8725
질문자

아 그러니까 클래스는 동적 할당의 특징이 있는게 아니라 "필요에 의해 그렇게 만들어진 것"이군요

그럼 Console.ReadLine()같은 입력받는 함수들도 모두 힙에 할당이 되는건가요?

mir8725님의 프로필 이미지
mir8725

작성한 질문수

질문하기