관리 메뉴

개발블로그

[유니티 에러]Error CS1503 StackOverflowException : The requested operation caused a stack overflow 본문

오류 해결

[유니티 에러]Error CS1503 StackOverflowException : The requested operation caused a stack overflow

dvmoo 2021. 7. 17. 18:35

StackOverflow Error

 


 

using UnityEngine;
using System;

public class StudyCoord : MonoBehaviour
{
    [SerializeField] GameObject _gbjCube  = null;

    Action _onBtn = null;

    // 버튼을 누르면 Cube의 로컬 좌표와 월드 좌표를 출력
    void Start()
    {
        CoordinateCubeLog(OnBtn);
    }

    void CoordinateCubeLog(Action onBtn)
    {
        _onBtn = onBtn;

        Debug.Log("Local Postion  : " + _gbjCube.transform.localPosition);
        Debug.Log("World Position : " + _gbjCube.transform.position     );

    }

    public void OnBtn()
    {
        _onBtn?.Invoke();
    }
}

✔ 문제의 코드

코드를 작성 후 실행하니 에러가 발생했다. 

StackOverflowException은 실행 스택에 중첩 메소드 호출이 너무 많아서 오버플로우 될 때 throw되는 예외이다.

 

 


🙋‍♀️ 여기서 잠깐,  Overflow란?

사전적인 의미로는 '넘치다', '넘쳐 흐른다' 등의 의미를 가지고 있다. 

이 사전적 의미를 프로그래밍에서 적용 시켜본다면,

100바이트를 저장할 수 있는 변수에 110바이트를 저장하려 한다면 그 이상은 넘쳐 흐를 것이다.

컴퓨터는 경고 메시지를 보여주거나 이를 무시하고 100바이트만 저장할 것이다.

 

이 때 발생한 상황이 바로 Overflow다. 

 


 

✔ 구현 의도

버튼을 눌렀을 때, Floor 오브젝트의 하위 오브젝트인 Cube의 로컬좌표와 월드좌표를 로그에 남기기.

 

 

 

✔  문제점 추론

그렇다면 작성한 코드를 실행해 보자. 

그림-1

유니티에서 Start() 함수는 스크립트의 인스턴스가 활성화되면 첫 번째 프레임의 업데이트 전에 한번만 호출된다.

저 상태에서 실행 버튼을 누르면 시작하자마자 콘솔창에 로그가 나타난다. (그림-1)

 

 

(1) 첫번째 잘못된 점

버튼을 누르면 로그가 찍히도록 구현 해야겠다고 생각했는데, 

Start()에서 CoordinateCubeLog() 함수를 실행하라고 명령 했으니 당연히 컴파일러는 런타임이 시작되자마자 로그를 띄운다. 

 

근데 이 부분에서 잘못된 부분이 또 있다.

바로 Action 부분인데, Action은 객체 전달을 위해 사용되는 타입이다.

하지만 이 클래스에서는 굳이 Action을 쓰지 않아도 정상적으로 실행할 수 있다.

 

 


🙄 나는 왜 Action을 사용했는가?

얄팍한 변명을 해보자면 처음에 내가 구현하려 했던 방식과 생각이다.

 

(1) 버튼을 누르면 실행하는 Action 타입의 _onBtn을 선언한다.

(2) 버튼을 눌렀을 때 _onBtn?.Invoke(); 로 null 체크 후 실행 한다.

(생각은 그렇게 했으나 사실 이 스크립트에서 Action은 쓸 이유가 없다. Action을 이용해 보고 싶어서 코드에 욱여 넣었지만 Too much 였던 것.

  _onBtn은  계속 null 상태이다. )

 


일단 수정은 마지막에 하도록 하고, 버튼을 눌러보았다.

버튼을 클릭하면 StackOverflow라며 경고를 띄운다.

 

 

 

(2) 두번째 잘못된 점

코드를 따라가면서 실행 순서를 머리 속에서 생각 해보자.

 

(1) Action타입의 _onBtn 변수는 null 상태이다. 

(2) 버튼을 눌렀을 때 OnBtn() 함수가 호출되면 _onBtn의 null 체크를 시도한다. 

(3) Start() 에서  CoodinateCubeLog(OnBtn); 을 통해서  _onBtn에 OnBtn이 들어간다.

(4) 다시 _onBtn변수는 Invoke하며 null값을 보내고, 다시 (3) 번이 반복되고, ... 반복되고... 무한 반복의 굴레에 빠진다.

 

 

버튼을 4번쯤 누르면 견디다 못해 에디터를 꺼버린다. (...)

 

 

 

✔ 문제점을 찾았다면 이제 코드를 수정해보자

using UnityEngine;
using System;

public class StudyCoord : MonoBehaviour
{
    [SerializeField] GameObject _gbjCube = null;

    // 버튼을 누르면 Cube의 로컬 좌표와 월드 좌표를 출력
    void CoordinateCubeLog()
    {
        Debug.Log("Local Postion  : " + _gbjCube.transform.localPosition);
        Debug.Log("World Position : " + _gbjCube.transform.position     );
    }

    public void OnBtn()
    {
        CoordinateCubeLog();
    }
}

 

코드가 상당히 깔끔해졌다.

 

 

실행도 정상적으로 잘 된다.

 

 

💪 이렇게 또 하나 배웠다!

아주 간단하게 짤 수 있는 코드였는데 배운걸 활용해보겠다고 억지로 Action을 끼워 넣었더니 이런 오류가 생겨버렸다.

이 코드의 오류를 수정하면서 느낀 점은 억지로 이것저것 넣어서 '멋져보이는 코드'가 아니라

내가 작성한 코드의 순서가 어떻게 돌아가는지 이해하고 직관적이고 가독성 좋은 코드를 작성 해야겠다고 생각했다.

 

 

 

 

 

* 공부하는 단계입니다. 잘못된 정보가 있다면 피드백 부탁드려요😊

* e-mail : heehee970@naver.com