배열 깊은 복사와 얕은 복사에 대해서

게임 개발을 하다 보면, 배열(혹은 리스트)의 데이터를 복사해야 할 때가 종종 있습니다.

그런데 C#에서 배열은 참조 타입이라 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)가 존재하여 사용할 때 혼동될 수 있습니다. Unity 프로젝트에서 발생할 수 있는 사례로 알아보겠습니다.

 


얕은 복사(Shallow Copy)란?

“원본과 같은 데이터를 가리키는 참조만 복사한다.”

즉, 배열 변수가 가리키는 메모리 주소(참조)만 복사하는 방식입니다. 원본 배열과 복사본 배열은 동일한 실체(데이터)를 공유하므로, 한쪽을 변경하면 다른 쪽에도 영향이 갑니다.

void Start()
{
    int[] originalArray = { 1, 2, 3, 4 };
    int[] shallowCopy = originalArray; // 얕은 복사

    // shallowCopy를 수정하면 originalArray도 영향을 받음
    shallowCopy[0] = 99;

    Debug.Log($"originalArray[0]: {originalArray[0]}"); // 99
    Debug.Log($"shallowCopy[0]: {shallowCopy[0]}");     // 99
}

originalArray와 shallowCopy가 같은 데이터(배열 내용)를 가리키게 되므로 값을 수정하면 원본 데이터도 수정이 됩니다. 조심히 다루어야 겠죠?


깊은 복사(Deep Copy)란?

“원본과 동일한 내용의 메모리를 새로 할당하여, 두 데이터가 서로 독립적으로 존재한다.”

즉, 배열 안의 각 요소들까지 전부 복사해 완전히 새로운 배열을 만들어냅니다.
원본 배열과 복사본 배열은 서로 다른 실제 데이터 가지게 되므로, 한쪽이 변해도 다른 쪽엔 영향이 없습니다.

Array.Copy

가장 쉬운 방법 중 하나는 Array.Copy로 새 배열을 생성한 뒤, 요소를 몽땅 복사하는 것입니다.

void Start()
{
    int[] originalArray = { 1, 2, 3, 4 };
    int[] deepCopy = new int[originalArray.Length]; //original Array 길이보다 작으면 Error!

    // 깊은 복사
    Array.Copy(originalArray, deepCopy, originalArray.Length);
    
    deepCopy[0] = 99;

    Debug.Log($"originalArray[0]: {originalArray[0]}"); // 1
    Debug.Log($"deepCopy[0]: {deepCopy[0]}");          // 99
}

이제 deepCopy의 값을 바꿔도 originalArray가 바뀌지 않습니다.