본문 바로가기
C#

C#] Value type은 어디에 저장되는가? Stack or Heap??

by Fastlane 2021. 12. 24.
728x90
반응형

참조 : https://youtu.be/jONSIhMST9E

Reference type은 항상 heap에 위치한다!

Value type은 어디서 생성되었는지에 따라서, stack, heap 양쪽에 위치한다

 

1. Main에 선언된 int : Stack

Main함수에 int변수값을 지정하고 어디에 저장되는지 확인해보자

 

포인터 관련 연산자 

& : 변수의 주소를 가져옴

* : 포인터가 가리키는 변수를 가져옴

 

포인터 관련 작업을 하기 위해서는 unsafe로 감싸야 한다. 

Main함수에 int number = 420;를 할당하면 변수 주소에 420이 저장되어 있음을 알 수 있다. 

 

2. Class 안에 선언된 int : Heap

그렇다면 int를 class안에 넣고 class 인스턴스를 생성하면 int는 어디에 저장될까?

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var application = new Application();
        }
    }

    public class Application
    {
        private int number = 36;
    }

}

class instance는 heap에 저장되었고, int값도 class instance와 함께 heap에 저장된 것을 확인할 수 있다. 

즉 어디에 위치하는지에 따라 heap에도 저장될 수 있다. 

 

3. 함수에 Parameter로 전달된 int : Stack

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var application = new Application();
            application.SomeMethod(420);
        }
    }

    public class Application
    {
        public void SomeMethod(int number)
        {
            
        }
    }

}

heap에 420이 저장되지 않았다. Method의 Parameter로 전달된 숫자는 Stack에 저장된다. 

 

4. 함수안에 변수로 선언된 int : Stack, Boxing처리된 int : Heap

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var application = new Application();
            application.PrintDateFromLocalVariables();
        }
    }

    public class Application
    {
        public void PrintDateFromLocalVariables()
        {
            int day = 18;
            int month = 12;
            int year = 2021;

            Console.WriteLine($"The date is : {day}/{month}/{year}");
        }
    }

}

Console.WriteLine()함수가 실행되지 전까지 숫자들은 Stack에만 저장된다. 

Console.WriteLine()내부의 string format이 실행되면서 int parameter들은 object로 boxing되고 heap에 저장된다. 

 

 

5. Class 필드로 선언된 DateStruct : Heap

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var application = new Application();
        }
    }

    public class Application
    {
        DateStruct dateStruct = new DateStruct
        {
            Day = 18,
            Month = 12,
            Year = 2021
        };
    }

    public struct DateStruct
    { 
        public int Day { get; set; }
        public int Month { get; set; }
        public int Year { get; set; }
    }

}

ref struct로 수정하면 Stack에만 위치하게 되고, 컴파일 에러가 발생한다. 

함수 내부로 옮겨주면 에러가 발생하지 않고, 항상 Stack에 위치하게 된다. 

 

 

정리해보자!

1. Value type declared as variable in method =>Stack

2. Value type declared as parameter in method => Stack

3. Value type declared as a member of a class => Heap

4. Value type declared as a member of a struct => Wherever the struct has been allocated

5. ref structs => Stack always!

 

728x90
반응형

댓글