Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일

C# - string 타입은 shallow copy일까요? deep copy일까요?

이런 글이 있군요,

언어별로 살펴본 Deep Copy와 Shallow Copy
; https://www.kowanas.com/coding/2021/01/02/deep-copy%EC%99%80-shallow-copy

위의 글에서 C#의 string을 deep copy로 분류해 놓았는데요, 사실 값 형식과 참조 형식의 차이점을 분명히 안다면 shallow copy라는 것을 잘 아실 것입니다. 정말 그런지 한 번 테스트를 해볼까요?

using System;

class Program
{
    public int value = 0xff;

    static unsafe void Main(string[] args)
    {
        string a = "test is good";
        string b = a;

        IntPtr ptrA = GetRefAddress(a);
        IntPtr ptrB = GetRefAddress(b);

        Console.WriteLine($"ptrA: 0x{ptrA.ToInt64().ToString("x")}");
        Console.WriteLine($"ptrB: 0x{ptrB.ToInt64().ToString("x")}");
    }

    private unsafe static IntPtr GetRefAddress(object pg)
    {
        TypedReference refA = __makeref(pg);
        return **(IntPtr**)&refA;
    }
}

/* 출력 결과
ptrA: 0x39f2ea8
ptrB: 0x39f2ea8
*/

보다시피 변수 a, b 모두 GC Heap의 0x39f2ea8 위치를 동일하게 가리키고 있습니다.

그런데, 사실 "언어별로 shallow copy와 deep copy"를 다룬다는 것은 좀 맞지 않습니다. 일례로 해당 글에서 C의 struct가 deep copy라고 설명하는데요. 그런데, 구조체를 다음과 같이 만든 경우가 있다면,

#include <iostream>

typedef struct tagMyStruct
{
    int a;
    int* pB;
} MyStruct;

int main()
{
    MyStruct a = { 5, new int(5) };
    MyStruct b = a;

    b.a = 6;
    *(b.pB) = 100;

    printf("%d, %d\n", a.a, *(a.pB));
    printf("%d, %d\n", b.a, *(b.pB));
}
/* 출력 결과
5, 100
6, 100
*/

아무도 MyStruct 타입이 deep copy라고 대답하는 경우는 없을 것입니다. 즉, 해당 타입의 내부 구현 코드가 deep과 shallow를 결정하는 언어도 있는 것입니다.

(첨부 파일은 이 글의 예제 코드를 포함합니다.)

그러고 보니, 예전에 쓴 글이 하나 생각나는군요. ^^

XML Serializer를 이용한 값 복사
; https://www.sysnet.pe.kr/2/0/577




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]



donaricano-btn



[최초 등록일: ]
[최종 수정일: 1/13/2021 ]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 쓴 사람
 




1  2  [3]  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
12547정성태3/3/2021164오류 유형: 699. 비주얼 스튜디오 - The 'CascadePackage' package did not load correctly.
12546정성태3/3/2021191개발 환경 구성: 545. github workflow/actions에서 빌드시 snk 파일 다루는 방법 - Encrypted secrets
12545정성태3/28/2021697.NET Framework: 1026. 닷넷 5에 추가된 POH (Pinned Object Heap) [7]
12544정성태3/28/2021374.NET Framework: 1025. C# - Control의 Invalidate, Update, Refresh 차이점 [2]
12543정성태3/12/2021303VS.NET IDE: 158. C# - 디자인 타임(design-time)과 런타임(runtime)의 코드 실행 구분
12542정성태3/3/2021328개발 환경 구성: 544. github repo의 Release 활성화 및 Actions를 이용한 자동화 방법
12541정성태2/18/2021414개발 환경 구성: 543. 애저듣보잡 - Github Workflow/Actions 소개
12540정성태3/28/2021428.NET Framework: 1024. C# - Win32 API에 대한 P/Invoke를 대신하는 Microsoft.Windows.CsWin32 패키지
12539정성태3/28/2021429Windows: 189. WM_TIMER의 동작 방식 개요파일 다운로드1
12538정성태3/28/2021569.NET Framework: 1023. C# - GC 힙이 아닌 Native 힙에 인스턴스 생성 - 0SuperComicLib.LowLevel 라이브러리 소개 [2]
12537정성태3/28/2021620.NET Framework: 1022. UI 요소의 접근은 반드시 그 UI를 만든 스레드에서! - 두 번째 이야기
12536정성태2/9/2021461개발 환경 구성: 542. BDP(Bandwidth-delay product)와 TCP Receive Window
12535정성태2/10/2021295개발 환경 구성: 541. Wireshark로 확인하는 LSO(Large Send Offload), RSC(Receive Segment Coalescing) 옵션
12534정성태2/17/2021461개발 환경 구성: 540. Wireshark + C/C++로 확인하는 TCP 연결에서의 closesocket 동작파일 다운로드1
12533정성태2/8/2021393개발 환경 구성: 539. Wireshark + C/C++로 확인하는 TCP 연결에서의 shutdown 동작파일 다운로드1
12532정성태2/6/2021319개발 환경 구성: 538. Wireshark + C#으로 확인하는 ReceiveBufferSize(SO_RCVBUF), SendBufferSize(SO_SNDBUF)
12531정성태2/5/2021326개발 환경 구성: 537. Wireshark + C#으로 확인하는 PSH flag와 Nagle 알고리듬파일 다운로드1
12530정성태2/5/2021403개발 환경 구성: 536. Wireshark + C#으로 확인하는 TCP 통신의 Receive Window
12529정성태2/4/2021332개발 환경 구성: 535. Wireshark + C#으로 확인하는 TCP 통신의 MIN RTO
12528정성태2/9/2021338개발 환경 구성: 534. Wireshark + C#으로 확인하는 TCP 통신의 MSS(Maximum Segment Size) - 윈도우 환경
12527정성태2/1/2021416개발 환경 구성: 533. Wireshark + C#으로 확인하는 TCP 통신의 MSS(Maximum Segment Size) - 리눅스 환경파일 다운로드1
12526정성태2/1/2021320개발 환경 구성: 532. Azure Devops의 파이프라인 빌드 시 snk 파일 다루는 방법 - Secure file
12525정성태2/1/2021257개발 환경 구성: 531. Azure Devops - 파이프라인 실행 시 빌드 이벤트를 생략하는 방법
12524정성태2/18/2021319개발 환경 구성: 530. 기존 github 프로젝트를 Azure Devops의 빌드 Pipeline에 연결하는 방법 [1]
12523정성태1/31/2021343개발 환경 구성: 529. 기존 github 프로젝트를 Azure Devops의 Board에 연결하는 방법
12522정성태1/31/2021329개발 환경 구성: 528. 오라클 클라우드의 리눅스 VM - 9000 MTU Jumbo Frame 테스트
1  2  [3]  4  5  6  7  8  9  10  11  12  13  14  15  ...