[20251212] - 막간; 참조 테스트(feat. Deepcopy)

SmartBear·2025년 12월 12일

참조 테스트

테스트 계기

Python 을 이용한 웹 개발을 수년간 진행한 적이 있다.
Python 은 모든 변수가 Object 로 되어 있어 딱히 값 타입의 변수가 없다.
그래서 개발 초반에 아무생각없이 List 를 제어하다가 버그를 만난 적이 많다.

>> a = [ 1,2,3 ]
>> b = a
>> b[1] = 4
>> print(a)
[1,4,3]
>> print(b)
[1,4,3]

참고로 Python 은 copy 모듈내 deepcopy 라는 함수가 있다

참조 타입을 잘 이해하는 사람은 당연히 위 내용이 맞다고 생각하지만,
초보자의 입장에서는 저게 왜 저렇게 되는지 이해하기 힘들다.
C# 에서는 call by valuecall by reference 가 엄연히 분리되어 있기 때문에 이러한 혼동은 오기 쉬울 것으로 보인다.

C# test code

int[] arr0 = { 1, 2, 3 };
int[] arr1 = arr0;
int[] arr2 = new int[arr0.Length];
arr0.CopyTo(arr2, 0);

arr1[1] = 4;

Console.WriteLine("arr0: " + string.Join(",", arr0));
Console.WriteLine("arr1: " + string.Join(",", arr1));
Console.WriteLine("arr2: " + string.Join(",", arr2));
arr0: 1,4,3
arr1: 1,4,3
arr2: 1,2,3

위 코드와 결과에서 보다시피, 배열을 그냥 불러와 새로 정의하면
새로 정의된 값에는 기 정의한 배열의 heap 주소가 들어가 결국 같은 heap 주소를 바라보게 되어
서로의 값에 대한 변동이 일어나고 만다.

반면에, CopyTo처럼 값 자체를 복사하는 함수를 사용하면 두 배열은 분리되는 것을 확인할 수 있다.

아래는 각 코드를 그림으로 표현 및 설명한 내용이다.

아쉬운점 🫣

stack 에 저장된 heap memory 주소를 직접 출력해 확인하고 싶었는데, 뭔가 IDE 설정 때문인지 빌드 설정 때문인지 안된다. Unsafe 기능을 없애면 된다고 하는데 찾아서 해봐도 해당 기능을 찾기가 쉽지 않다 😑
나중에 진짜 해당 내용에 대한 디버깅이 필요할 경우 다시 찾아보기로 한다.

profile
Python Dev with Infra -> Game Programmer

0개의 댓글