C# Practicing(C#의 자료구조)

2023. 10. 24. 15:01Game Develop/C# Programming

오늘은 Insert 메서드의 마지막 문장 arr = resultArr;를 ref를 쓰면 왜 바꿔줄 수 있는지 자료구조로 설명해보겠다.

 

C#의 메모리 영역은 크게 4가지로 나뉜다(Stack, Heap, Data, Code). 오늘 설명할 것은 이중 Stack과 Heap으로 설명할 수 있다.

 

그렇다면 Stack 영역과 Heap 영역은 무엇일까?

 


값 형식(Value Type)이 들어가는 메모리 공간이다. 일반적인 value type인 int, char, bool 같은 것이 있다. (string은 reference type이다) 사용자가 선언한 struct도 value type으로 stack에 저장된다. 선언되었던 코드 블록이 끝나면 자동으로 메모리에서 해제된다.

 

참조 형식(reference type)이 추가되는 메모리 공간이다. 코드 블록과 상관없이 데이터가 사라지지 않는다. 참조 형식의 변수는 heap과 stack 영역을 동시에 이용하는데 heap 영역에는 데이터의 값을 저장하고, stack 영역에는 데이터의 주소를 저장한다. 따라서 코드 블록이 끝나는 순간 stack에 있는 데이터의 주소는 사라지지만 heap 영역에 존재하는 데이터의 값은 남아있게 된다. C#에서는 가비지 컬렉터(GC : Garbage Collector)가 주기적으로 heap을 청소한다.

 

자 우선 ref를 안썼을때 어떻게 작성해야 하는지 알아보자

 
 
매개변수로 정수형 배열, index 값, value 값을 갖는 InsertNum 메서드를 만들고 resultArr를 arr의 길이보다 1 크게 만들어 조건에 맞게 arr의 값과 value를 집어 넣어주었다. 그런 다음 arr에 resultArr에 arr을 대입했었다.
 
 
위 처럼 메인을 작성해주고 실행해주면 어떻게 될까?
 
우린 분명 InsertNum을 정확히 작성 했고 매개 변수도 문제 없이 잘 대입해주었지만, 값이 전혀 바뀌지 않았다. 왜 이럴까?

답은 위에서 말한 Stack 메모리에 있다.

 

우린 InsertNum 메서드의 형식에 맞게 매개변수로 각각 정수형 문자열, 정수형 index, 정수형 value, 값을 넣고 메인의 InsertNum(arr, 2, 99); 라인을 통해 메서드를 실행시켜 주었다.

 

문제는 여기서 발생한다. 우리가 매개변수로 넘겨준 각 값은 그 자체가 아니라 똑같은 값을 대입해준다고 생각하면 된다. 메서드는 그 값을 가지고 안의 실행문들을 실행을 하고 Stack 영역의 특성인 선언되었던 코드 블록이 끝나면 자동으로 메모리에서 해제된다. 즉, 메인에서의 arr과 insertNum 메서드의 매개변수 arr은 같은 것이 아니라는 것이다. 따라서 메서드 안 arr에 resultArr를 대입한 후 메인이 아닌 메서드에서 출력하는 실행문을 작성하면 원하는 값이 나올 것이다.

 
 
실행 결과에선 원하는 값이 나온 걸 확인할 수 있다.

 

그림을 통해 정리해보자면

 
 

따라서 메서드 내에서 InsertNum의 매개변수는 2000을 가리키고 있기 때문에 resultArr의 데이터를 출력할 수 있다.

 

Main이 끝날때 까지 arr의 데이터는 변한 적이 없다....

이번엔 ref를 써주었을 때의 자료 구조를 그림으로 표현하겠다

InsertNum(arr, 2, 99); 까지의 Main의 자료구조는 위의 그림과 변함 없다.

다만 InsertNum 메서드에서는 변화가 생긴다.

 
arr = resultArr; 실행전
 
arr = resultArr; 실행후
ref를 쓰면 Main의 arr가 가리키는 주소값 자체를 '참조'하여 바꿔주기 때문에 1000 에서 1111로 바뀌어서 힙의 1111 주소의 데이터를 가리킨다. 여기서 기존의 1000에 있던 데이터는 Garbage Collector에 의해 알아서 메모리 반환이 된다.

 

'Game Develop > C# Programming' 카테고리의 다른 글

C# Practicing(파일 입출력)  (0) 2023.10.24
C# Practicing(스레드)  (1) 2023.10.24
C# Practicing(Generic Programming2)  (0) 2023.10.24
C# Practicing(Generic Programming1)  (0) 2023.10.24
C# Practicing(Property 응용)  (0) 2023.10.24