C# 에서 "구조체(struct)는 스택에 저장된다" 는 말을 자주 들어봤을 것입니다. 그런데 배열은 "힙에 저장된다"고 합니다. 그렇다면 "구조체를 배열로 만들면 어디에 저장될까?" 하는 궁금증이 생깁니다.
이 글은 바로 그 궁금증을 풀기 위해 정리한 내용입니다.
구조체는 기본적으로 스택에 저장
다음처럼 지역 변수로 구조체를 선언하면, 이 변수는 스택(stack)에 저장됩니다:
void MyMethod()
{
MyStruct s = new MyStruct(); // 스택에 저장됨
}
값 타입(struct, int, float, bool 등)은 참조 타입(class)과 달리 스택 메모리에 저장되는 것이 일반적입니다.
배열은 힙에 저장 (new 없이도)
C#에서 배열은 참조 타입입니다. 즉, 배열 자체는 무조건 힙(heap)에 저장됩니다. 그리고 배열을 초기화할 때 new 키워드를 생략하더라도, 내부적으로는 자동으로 new가 발생하여 힙에 메모리가 할당됩니다
( C++에서는 new 없이 배열을 선언하면 스택에 저장되기 때문에, 이 부분이 C# 과의 큰 차이점 중 하나입니다. )
// 힙에 저장
int[] numbers = new int[5];
// 이것도 힙에 저장
MyStruct[] segments = new MyStruct[5];
// new 없이도 힙에 저장
int[] nums = { 1, 2, 3 };
구조체는 값 타입이기 때문에, new로 초기화하든 그렇지 않든 지역 변수로 선언되면 스택에 저장됩니다.
그러나 이 구조체를 배열이나 리스트 같은 참조 타입 컨테이너에 넣는 순간, 해당 구조체는 값 복사를 통해 힙에 저장됩니다.
즉, 구조체 인스턴스 자체가 이동하는 것이 아니라, 힙 쪽에 구조체의 복사본이 생기는 것입니다.
이후 지역 변수로 존재하던 구조체는 함수 종료와 함께 사라지지만, 컨테이너 내부에 저장된 복사본은 계속 유지됩니다.
이 힙에 저장된 복사본은 참조 타입 컨테이너가 유지되는 동안 계속 살아 있으며, 더 이상 사용되지 않으면 가비지 컬렉터(GC)의 대상이 됩니다.
요점은, “값 타입도 참조 타입 컨테이너에 담기면 힙으로 복사된다” 는 점입니다.
클래스 안에 있는 구조체도 힙에 저장
클래스는 참조 타입이기 때문에 힙에 저장됩니다.
클래스 내부에 구조체 필드가 있다면, 해당 구조체는 클래스 인스턴스의 일부로 함께 저장됩니다.
즉, 배열이나 리스트의 경우처럼 구조체가 스택에 존재했다가 힙으로 복사되는 것이 아니라, 클래스가 힙에 존재하기 때문에 그 안에 포함된 구조체도 처음부터 힙 메모리 내에 위치하게 되는 것입니다.
class MyClass
{
// 이 구조체는 MyClass 인스턴스의 일부로 힙에 저장됨
public MyStruct segment;
}
마무리
구조체는 기본적으로 스택에 저장되지만, 배열 안에 들어가거나 클래스 안에 포함되면 힙에 저장됩니다. 즉, 값 타입이라는 것과 힙/스택의 저장 위치는 다르게 봐야 하는 개념입니다.
값 타입도 힙에 갈 수 있다. 이것이 C# 메모리 모델의 중요한 포인트입니다.
'C#' 카테고리의 다른 글
delegate 를 더 간결하게 선언하는 방법 (0) | 2025.04.23 |
---|---|
bool isValue = (조건식) : 삼항 연산자를 보다 단순하게 (0) | 2025.04.22 |
int.TryParse() 와 Convert.ToInt32() 중 어떤 걸 써야하나? 고민된다면 (0) | 2025.04.02 |
C# 에서 ref, out, in 키워드 정리 (0) | 2025.04.02 |
C# 에서 readonly 는 참조 타입에서 어떻게 동작할까? (0) | 2025.04.01 |