inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

유니티(Unity)로 시작하는 게임개발: Part 2. C# 프로그래밍 입문

스택영역과 힙영역

앞선 강의에서 Instance와 연관 지어서

269

Hyobin Kim

작성한 질문수 81

0

해당 강의에서 

참조 당하는 실제 데이터는 힙에 존재하고 있고 메모리 관리자가 계속해서 확인하면서 참조 당하는지를 본다고 하셨잖아요?

여기서 playerScript의 실제 데이터를 언급하셨는데

만약에 제가 두개의 플레이어 Instance를 게임에서 만들었으면

당연히 두개의 playerScript의 실제 데이터가 다른 주소의 힙 영역에 존재하게 되고, 스택에 있는 참조 변수(?)는 그 자체에 맞는 실제 데이터를 참조하게 되는거죠?

C# unity

답변 3

0

UDevApp

다시 위의 예제에서 테스트스크립트를 멤버변수로 선언했다면 이야기가 또 다릅니다. 

스타트가 실행되어 스택은 생겨나더라도 변수자체는 스택에 생기지 않습니다.

멤벼변수에 값을 대입했기에 아래 그림처럼 구조가 생겨납니다. 

public class TestScript : Monobehaviour{

    PlayerScript playerScript ; // 멤버변수

    void Start(){

        playerScript = GetComponent<PlayerScript>(); 

    }

}

0

UDevApp

위의 상태에서 함수 안에서 스택 변수를 생각해보면  다음과 같습니다. 

자기 자신의 플레이어 스크립트를 참조한다고 생각하면 조금 이상하므로 테스트스크립트를 하나 넣어서 확인해봐야 할것 같습니다. 

구조가 아래와 같습니다. 플레이어1만 남겨두고 그 안에 PlayerScript와 TestScript 를 넣었습니다. 

이상태를 메모리 구조를 보면 다음과 같습니다. 

이제 테스트스크립트가 있고 "스타트 함수" 안에서 playerScript 가 있습니다. 이 변수는 스타트함수의 스택에 있습니다. 그래서 playerScript 의 변수도 함수가 끝나면 없어지게 됩니다. 그래도 이것도 레퍼런스 변수이기 때문에 실체에 있는 PlayerScript 의 인스턴스를 참조하게 될 것입니다. 

public class TestScript : Monobehaviour{

    void Start(){

        PlayerScript playerScript = GetComponent<PlayerScript>(); 

    }

}

그림으로 보면 다음과 같습니다. 함수 안에서 스택이 생겨납니다. 

실제로 노란색의 사각형이 스택이고 Start 함수가 끝나면 스택과 함께 변수가 사라집니다

그래도 현재 이순간 이 플레이어 스크립트의 레퍼런스변수가 다음과 같이 실제의 PlayerScript 인스턴스를 가르킵니다.  

위의 그림과 아래의 그림을 잘 확인해보세요.(제일오른쪽의 화살표가 playerScript 의 스택변수(레퍼런스)가 실제 플레이어스크립트의 인스턴스를 가르킵니다.) 

그래서 스타트 함수 안에서 playerScript.hp = 10; 과 같은 작업을 진행할 수 있는 것입니다. 

0

Hyobin Kim

playerScript.hp = 10 이 부분에서 조금 더 확장해 나가면,

제가 만약 게임이 시작할 때 딱 한번만 HP 를 10으로 설정을 하고 싶습니다

그럼 위의 댓글 대로 해도 playerScript의 hp 변수에는 10이라는 값이 그대로 남아있는거죠?

저 경우에, PlayerScript playerscript로 선언된 Start() 내부의 참조변수는 start()가 끝나면 사라지겠지만, 어쨋거나 저 참조변수를 통해서 playerScript라는 실제 데이터(인스턴스)에 접근해서 hp라는 heap 에 존재하는 변수에 10이라는 값을 넣어준 거니까요

0

UDevApp

질문이 올라온 것을 몰라서 답변이 늦었습니다.

거의 맞는 것 같은데요 스택하고 멤버변수가 조금 혼돈 스러운건 아니신지 하는 생각이 듭니다. 

예를 한번 들어보겠습니다. 

플레이어1과 플레이어2의 오브젝트가 있고 각각 플레이어스크립트가 있다고 해보겠습니다. 

이경우 메모리가 다음과 같습니다. 

여기에서는 스택이 없습니다. 함수가 있고 실행되는 곳이 있을때 스택이 생겨납니다. 

또한 "플레이어1의 게임오브젝트의 변수"와 "플레이어2의 게임오브젝트의 변수" 라는 것도 사실 저희 눈에는 보이지 않습니다. 하지만 이것도 클래스이므로 레퍼런스변수이며  내부적으로 있고 유니티의 계층뷰에서 이것을 관리할 것입니다.  "실제 데이터는 플레이어1의 게임오브젝트"의 사각형입니다. 

또한 "플레이어2의 게임오브젝트라는 변수"도 레퍼런스 변수이고 유니티의 계층뷰에서 관리합니다. 실제 데이터는 "플레이어2의 게임오브젝트" 라는 사각형입니다. 

그리고 마찬가지로 각각의 게임오브젝트안에 있는 playerScript 라는 것도 이것은 레퍼런스 변수입니다.

1번변수인 playerScript 는 변수이지만 저희가 볼수 없고 이것이 레퍼런스변수 입니다. (컴포넌트로 관리되고 있죠 게임오브젝트에 부착되어 있고 이것도 클래스이므로 레퍼런스가 있고 실제 인스턴스가 있습니다.) 

1번 변수의 인스턴스는2번 사각형입니다.

마찬가지로 3번도 플레이어2에서 관리하는 컴포넌트로 되어 있으며 내부적으로 playerScript 라는 변수가 내부적으로 있을 것입니다. 실제 데이터는 4번 사각형입니다. 

그러므로 여기에 있는 파란색의 사각형 전부 다 인스턴스가 됩니다. 가비지 컬렉터가 힙으로 관리를 하겠죠.

0

Hyobin Kim

컴포넌트랑 참조변수

이렇게 표현해도 좋을까요?

게임오브젝트에 스크립트를 부착하면, 이 스크립트, 즉 이 클래스는 컴포넌트라는 인스턴스로 관리된다

Part4 유니티로 세가지의 게임만들기 강의도 들을 수 있는건가요?

0

262

1

플레이 버튼이 없어요

0

757

1

전체 연습문제 다운방법, 현재 연습문제 파일이 깨져서 열립니다.

0

376

2

연습문제파일

0

262

1

중단점을 찾을수가 없습니다

0

469

1

10분 24초에 만약 b를 0으로 둘시, "나눗셈이 불가능"대신 attempt to divide by zero 오류가 뜹니다.

0

312

1

if문의 비교(10분56초~59초사이)

0

219

1

NullReferenceException을 기대했는데....

0

326

1

C#에서의 메모리 관리

0

273

1

Heap 과 Stack

0

303

1

Instance와 variable

0

243

1

구조체 6번째 강의

0

190

1

제공 함수는 실제 구현하는 몸체가 없다

1

341

1

인자와 매개변수

1

215

1

코드에서 new GameObject를 실행했을 때 유니티 화면상의 상태 문의

2

621

1

유니티 콘솔화면에 나타난 내용 문의

1

353

1

멤버변수를 전역변수라고 생각해도 되는지요?

1

1225

1

출력만 있는 함수 관련 질문

1

422

2

문제 파일은 어디에 있나요?

0

234

1

제 윈도우용 visual studio에서는 코드행 앞에 아무것도 안찍힙니다.

0

319

2

혹 강의내용을 캡쳐해서 블로그에 공개해도 되나요?

0

364

1

비쥬얼 스튜디오에서 강의대로 입력했는데 콘솔창에 아무것도 안나타나네요.

0

262

1

저는 윈도우즈에서 모니터를 두개로 나눠 강의영상과 Unity작업창으로 나눠서 하고 있는데 무슨 얘긴지 하나도 모르겠어요

0

229

2

갑자기 파일을 추가하려면 과정을 설명해 주셔야 하는데 그냥 파일부터 추가하네요.

0

171

1