c# 메모리 할당(정적할당, 동적할당)

JHO·2024년 7월 12일
0

c#스터디

목록 보기
1/9

1. 메모리 할당


1-1. 값 타입과 참조 타입

  • c#에서의 변수는 값 타입참조 타입으로 나눠 지고,
  • 값 타입은 정적 할당으로 Stack 메모리에 저장된다.
  • 참조 타입은 변수자체는 Stack메모리에, 실제 데이터는 동적 할당으로 Heap 메모리에 저장이 된다.
    -> 즉, new를 통해 실제 데이터를 힙에 저장하면, 스택에 저장되어있는 변수(포인터)가 가리키는 형태이다.
  • 값 타입은 null을 사용하지 못하지만, 참조 타입은 null을 사용할 수 있다.
    -> 값 타입에 null 값을 사용하고 싶으면 자료형뒤에 ?을 붙이면된다.(nullable사용) ex) int? a;
  • 이 때, static을 선언한 변수는 정적변수로 모두 Data 영역에 저장이 된다.

1-2. 값 타입의 종류

  • Built-in(bool, char, short, int, long, float ~)
  • Struct

1-3. 참조 타입의 종류

  • Class
  • interface
  • Delegate
  • Array(배열)
  • Object
  • Dynamic

2. class안에 값 타입의 인스턴스변수가 있다면 이는 어디에 저장이 될까?


public class MyClass {
    private int myField; // 인스턴스 변수
    public MyClass(int value) {
        myField = value;
    }    
    public void DoSomething() {
        Console.WriteLine("Value of myField: " + myField);
    }
}
public class Program {
    public static void Main() {
        MyClass obj = new MyClass(42); // MyClass의 인스턴스 생성
        obj.DoSomething(); // 인스턴스 메서드 호출
    }
}
  • 위를 예시로 들면, new MyClass(42)를 호출하면 MyClass의 instance가 heap에 할당된다.
  • obj 변수 자체는 stack에 저장되며 이 변수는 heap에 할당된 instance의 메모리 주소를 참조한다.
  • obj안의 인스턴스 변수 myField도 instance의 일부로서 myField또한 heap 메모리에 같이 저장된다.
    -> 값 타입의 변수라 할지라도, 인스턴스 변수일 경우 클래스와 함께 힙에 저장되고, 지역 변수의 경우는 스택에 저장된다.

3. struct안에 참조 타입의 멤버변수가 있다면 이는 어디에 저장이 될까?


public struct MyStruct {
    public int value;       // 값 타입 변수
    public int[] array;     // 참조 타입 변수
}
public class Program {
    public static void Main() {
        MyStruct myStruct = new MyStruct();
        myStruct.value = 10;
        myStruct.array = new int[] { 1, 2, 3, 4, 5 }; // 배열은 힙 메모리에 저장됨        
        Console.WriteLine(myStruct.value);  // 출력: 10
        Console.WriteLine(myStruct.array[0]); // 출력: 1
    }
}
  • 위를 예시로 들면, myStruct은 구조체이므로 stack 메모리에 할당된다.
  • array변수는 참조 타입이지만 구조체 안에 포함되므로 할당될 때 참조 타입(포인터)으로 같이 stack영역에 저장된다.
  • new int[]{1,2,3,4,5};를 선언하면, 실제 배열 데이터는 heap에 할당이 된다.
  • stack에 있는 array변수(포인터)가 heap에 저장된 실제 데이터의 메모리 시작주소를 참조한다.
profile
개발노트

0개의 댓글