Unity 개발일지

[C#] Struct(Stack 메모리) vs Class(Heap 메모리) 실습하기 본문

C#

[C#] Struct(Stack 메모리) vs Class(Heap 메모리) 실습하기

아머르 2024. 7. 4. 21:25

[확인 문제]

1. 다음 struct 코드와 class 코드의 결과를 예측해보고, 이유를 생각해봅시다.

더보기

[Struct 의 결과]

Point 1 X: 10

Point 2 X: 30

 

[이유]

Point는 struct로 정의되어 있어 값 형식이다.

point2는 point1의 값을 복사받아 독립적인 인스턴스가 된다.

따라서 point2.X를 수정해도 point1.X는 영향을 받지 않는다.

 

[Class 의 결과]

Point 1 X: 30

Point 2 X: 30

 

[이유]

Point는 class로 정의되어있어 참조 형식이다.

point2는 point1과 동일한 인스턴스를 참조하게 된다.

따라서 point2.X를 수정하면 point1.X도 영향을 받아 동일한 값을 갖게 된다.

 

[설명 문제]

1. 참조 형식과 값 형식에 대해 설명해주세요.

더보기
  • 참조 형식: 객체의 주소를 저장하며, 같은 객체를 여러 참조가 가리킬 수 있다. 예: class, string, array.
  • 값 형식: 데이터 자체를 저장하며, 복사하면 독립적인 복사본이 만들어진다. 예: struct, int, float.

 

2. 메모리에서 스택과 힙의 차이점에 대해 설명해주세요.

더보기
  • 스택: 함수 호출과 관련된 지역 변수와 매개변수를 저장하며, LIFO(Last In, First Out) 방식으로 관리됩니다. 빠른 메모리 할당/해제의 이점을 가진다.
  • : 동적으로 할당된 객체가 저장되며, 관리 및 정리가 복잡하고 가비지 컬렉션을 통해 메모리 해제가 이루어집니다. 상대적으로 느린 메모리 접근을 가진다.

 

3. 1번과 2번 질문의 답안을 기반으로 struct와 class의 차이점에 대해 설명해주세요.

더보기
  • 값 형식(struct): 데이터 자체를 복사하며, 주로 작은 데이터를 저장하는 데 사용된다.
  • 참조 형식(class): 데이터의 참조를 복사하며, 동적 할당과 복잡한 데이터 구조를 저장하는 데 적합하다.

 

4. 얕은 복사와 깊은 복사의 차이점은 무엇인가요?

더보기
  • 얕은 복사: 객체의 필드만 복사하고, 그 필드가 참조형일 경우 참조된 객체까지는 복사하지 않는다.
  • 깊은 복사: 객체와 그 객체가 참조하는 모든 객체를 재귀적으로 복사하여, 완전히 독립적인 복사본을 만든다

 

5. 박싱과 언박싱이 일어나는 과정을 메모리 관점에서 설명해주세요.

더보기
  • 박싱: 값 형식을 힙에 할당하고 참조 형식으로 변환하는 과정입니다. 스택에 저장된 값을 힙에 저장된 객체로 감싸고 참조를 스택에 저장한다.
  • 언박싱: 참조 형식을 값 형식으로 변환하는 과정입니다. 힙에 저장된 값을 스택에 다시 복사하여 값 형식으로 만든다.

 

[실습 문제]  여러 종류의 깊은 복사를 구현해봅시다.

1. 새로운 인스턴스를 생성하여 모든 필드들을 복사한 뒤 반환해주는 Clone() 메서드

2. 복사 생성자를 이용한 깊은 복사

 

더보기
public class Character
{
    public string name;
    public int hp;
    public int attack;

    public Character()
    {
        name = "";
        hp = 10;
        attack = 5;
    }

   // Clone 메서드 구현 (깊은 복사)
    public Character Clone()
    {
        return new Character()
        {
            name = this.name,
            hp = this.hp,
            attack = this.attack
        };
    }

    // 복사 생성자 구현 (깊은 복사)
    public Character(Character original)
    {
        this.name = original.name;
        this.hp = original.hp;
        this.attack = original.attack;
    }
}

 

 

반응형