나의 브을로오그으

깊은 복사와 얕은 복사[C#] 본문

c#/c#기본 문법

깊은 복사와 얕은 복사[C#]

__jhp_+ 2022. 1. 12. 16:52

오늘은 c# 공부를 하면서 깊은 복사와 얕은 복사에 대해서 알아봤다.

이름 그대로 deep copy는 깊은 복사,

shallow copy는 얕은 복사이다.

 

c#에서는 우선 다음에 주목해야 한다.

deep copy든 shallow copy든

둘다 어쨌든 copy라는 점이다.

스택 메모리의 저장된 값을 복사하는 데에는 둘다 동일하다.

 

            int n1 = 4;
            int n2 = n1; // 값 복사 : deep copy(깊은 복사)

 

위의 코드에서 보면

n1에 4라는 값을 할당했다.

정확하게는 스택의 메모리를 할당하여 4라는 값을 저장하고

n1이라는 식별자를 붙여 메모리를 접근하여 값을 변경 할 수 있는 것이다.

 

n2 = n1은 직관적으로는 n2에 n1의 값을 넣는것 같지만

정확하게는 스택에 메모리를 새로 할당하여 n1에 저장된 4라는 값을 복사하여

새로 할당한 메모리에 저장한다.

그리고 그 메모리의 식별자로 n2를 붙이는 것이다.

근대 이것만으로는 deep copy에 대한 개념이 부족하다. 단순 복사일 뿐이니

 

이런 상황이 있다고 생각해 보자.

        private static void ChangeValue(int n)
        {
            n = 50;
        }

        static void Main(string[] args)
        {
            int n = 10;
            ChangeValue(n);
            Console.WriteLine(n);
        }

 

 

콘솔에 출력을 해보면 n값이 50으로 나올까?

결론부터 말하면 n은 10으로 출력된다.

이유는 위에서 설명한 바와 같다.

 

변수 n을 ChangeValue의 인수(인자)로 넘기면

메모리상에서는 임시 객체가 생성된다.

즉, ChangeValue의 파라미터 n은 우리가 Main에서 생성한 변수 n과는 다른 값이라는 의미이다.

 

변수 n을 넘기는 것 같지만

새로운 메모리를 스택에 할당하고, 할당된 메모리에 n값을 복사하여 저장한다.

ChangeValue(int n)메소드 안에서 n의 값을 바꾸어 봤자

새로 할당된 메모리의 n의 값이 바뀌는 것이기 때문에

Main문의 n값은 변하지 않는다.

 

다음으로 얕은 복사를 알아보면 다음과 같다.

    class Point
    {
        public int x;
        public int y;
        public override string ToString()
        {
            return "X: " + x + ", Y: " + y;
        }
    }

    class Program
    {
        private static void Change(Point pt)
        {
            pt = new Point();
            pt.x = 6;
            pt.y = 12;
        }
        
        static void Main(string[] args)
        {
            Point pt = new Point();
            pt.x = 10;
            pt.y = 20;
            Console.WriteLine(pt);

            Change(pt);
            Console.WriteLine(pt);
        }
    }

 

위와 같은 경우에 콘솔을 출력해보면 x와 y의 값이 어떻게 나올까?

결과는 6과 12가 나온다.

 

Change()메소드를 호출 시 pt를 인수로 넘기면

위와 동일하게 값의 복사가 일어난다.

 

근대 여기서 클래스는 참조형식 이므로

Main()메소드의 pt변수에는 스택 메모리에는 힙 메모리 주소가 저장되어 있다.

 

즉, Change(Point pt)메소드의 파라미터 pt는 새롭게 스택에 할당된 메모리의 식별자이고

힙의 메모리 주소를 복사했기 때문에

Main문의 pt와 Change(Point pt)의 파라미터 pt에 저장된 힙의 주소를 참조하여

값을 변경하게 되므로 콘솔에 x,y값이 변경되어 출력된다.

 

출처 : http://www.yes24.com/Product/Goods/97314203

 

시작하세요! C# 9.0 프로그래밍 - YES24

이 책의 목표는 확실하다. 여러분이 프로그램을 만들고자 할 때 사용하게 될 C# 프로그래밍 언어의 기초를 단단하게 다질 수 있게 하는 것이다. 이 책에서는 C# 언어의 최신 버전인 C# 9.0의 문법까

www.yes24.com