• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    미해결

node의 child

20.12.03 03:01 작성 조회수 151

1

이런 경우를 몇번 봤는데

node의 child의 경우 new TreeNode<string>()해서 추가 하잖아요

이럴경우 변수의 이름이 없는 상태로 메모리 할당 될텐데

 이름을 지정하지 않는 특별한 이유가 있는건가요?

답변 3

·

답변을 작성해보세요.

1

네, 기본적으로 맞게 설명하셨지만
TreeNode<T>가 참조형인 것과는 무관하게 List 자체가 참조형입니다.
그러니 List<int> Children {get; set;} 상황에서도
Children 초기값을 넣어주지 않으면 마찬가지 상황이 발생합니다.

추가로 C# 참조라고 특별히 다른 CPU를 활용하는 것은 아니고,
내부적으로는 C포인터와 마찬가지로 주소값을 이용해 동일하게 작업합니다.

1

변수의 이름은 꼭 필요한게 아니고,
필요할 때 접근을 할 수 있으면 됩니다.
예를 들면 int[] arr 이라는 배열이 있으면
각 요소를 인덱스를 이용해 arr[2] 이런 식으로 접근 가능하니,
모든 데이터에 다 이름을 일일히 지을 필요는 없겠죠.
마찬가지로 트리도 루트 노드만 알고 있으면
이리 저리 이동해서 모든 데이터에 접근하니 굳이 이름이 필요 없습니다.

그리고 [변수의 이름이 없는 상태로 메모리가 할당된다]라고 하셨는데
엄밀히 말해 '변수의 이름'이라는 것은 우리한테 편리하게 존재하는 것이지,
로우레벨 관점에서 컴파일이 된 다음에는 존재하지 않는 개념이고
단순히 해당 메모리 주소에 작업을 하도록 적절하게 주소로 치환이 됩니다.
따라서 이름을 붙이지 않는다고 뭔가 정보 손실이 있다거나 한 것은 아닙니다.

마지막으로 TreeNode가 힙에 올라가는 참조값인 경우에서
var node = new TreeNode<string>()으로 했다고 가정하면,
node라는 것은 TreeNode 변수에 이름을 지어줬다기 보다는
단순히 참조값, 즉 [주소를 저장하는 바구니]에 가깝고
그 참조값을 저장하는 바구니의 이름이 'node'인 것입니다.
이는 C++ 포인터를 공부하면 더 쉽게 이해가 가능한데
그림으로 표현하면 다음과 같습니다.

0

Hyobin Kim님의 프로필

Hyobin Kim

질문자

2021.01.09

이전에 C언어 공부할 때 포인터 까지 배웠는데 그게 연상이 되네요 감사합니다

한가지 더 질문을 하고 싶은데요

        public List<TreeNode<T>> Children { get; set; } = new List<TreeNode<T>>();

솔직하게 필드를 프로퍼티로 설정한 뒤에 (표현이 맞는가 모르겠습니다) 생성자를 추가하는 경우는 처음봅니다

생성자 부분을 지우면 어떻게 되는가 보려고 지우고서 빌드를 해봤는데, MakeTree() 함수에서 Children에 접근해서 Add하는 부분에서 NullReferenceException이 뜨더군요

추측컨데, 우선 제가 프로퍼티에 생성자가 필요한 경우를 처음본 이유는 제가 여태까지 본 코드에서는 프로퍼티는 보통 참조형이 아닌 값형, 즉 int나 float 등이었기 때문일거라고 생각합니다

NullReferenceException의 발생원인은 위에서 말했듯 TreeNode<T> 클래스는 참조형이고 내부에 동일 클래스의 Children이라는 이름의 인스턴스를 참조하는 중이기 때문일거라고 생각합니다. 따라서, MakeTree()에서 생성된 node 변수에서 Children을 접근하려고 해도 생성된 Children 인스턴스가 없기 때문에 NullReference가 뜬 거죠?