구조체 배열을 선언하면 메모리 관점에서 어떤 일이 발생하는지 그 과정에 대해 한번 알아보겠습니다.
예제 코드
public struct StageData
{
public int ballSpeed;
public int blockColumn;
public int blockRow;
}
StageData[] arr = new StageData[5];
배열은 힙(Heap) 에 생성
• StageData[]는 참조 타입이므로 힙에 5개짜리 배열 공간이 생성됩니다.
• 그리고 StageData는 구조체(값 타입) 이므로, 배열 안에는 구조체가 들어갑니다.
• 즉, 힙에 구조체 5개 짜리 데이타 공간이 생성되는 것입니다.
각 요소는 자동 초기화
• new StageData[5]를 하면, C#은 각 구조체를 default 값으로 자동 초기화합니다.
• 따라서, arr[0]부터 arr[4]까지는 모두 다음 값으로 초기화됩니다.
• 만약 구조체 안에 참조 타입 필드가 있으면, 그 값은 null로 초기화됩니다.
ballSpeed = 0
blockColumn = 0
blockRow = 0
new 는 힙에 공간을 생성하거나, 스택이라면 해당 크기 만큼 공간을 사용할 수 있도록 하는 역할만을 합니다.
그리고 new 뒤에 따라오는 [ ] 나 ( ) 또는 { } 로 default 생성자 등을 호출하여 값을 자동 초기화합니다.
// 컴파일 오류 (X)
StageData stageData = new StageData;
만약, new 가 값을 초기화하는 기능까지 있다면, 위와 같은 코드가 성립되어야 하는데 이런 코드는 없습니다.
즉, new 단독으로는 쓰일 수가 없고 뒤에 초기화하는 무언가가 반드시 뒤따라 오게 되어 있습니다. 그렇게 때문에 흔히 new 로 초기화 라는 말을 하는데, 엄밀히 말하면 new 로 먼저 공간 (참조 형식이면 힙에 동적으로 생성, 값 형식이라면 스택에 공간을 점유) 을 마련하고 초기화 라는 말이 더 정확합니다만, 대부분은 (거의 모두에 가까움) 이렇게 말하지 않기 때문에 우리는 이것을 분리해서 잘 생각하지 않게 되는 것 같습니다.
구조체 필드에 값 대입
어쨌거나, new StageData[5] 로 구조체의 각 필드는 0 으로 자동 초기화된 상태입니다.
이제, 원하는 값으로 초기화시켜야 합니다.
new StageData { ballSpeed = 5, blockColumn = 5, blockRow = 3 };
여기서 new 는 구조체 StageData 를 스택 또는 레지스터에 임시 저장 보관소를 만드는 역할을 합니다.
공간만 마련된 상태이기 때문에, 이제 값을 채워넣어야 합니다.
다음 코드가 그 역할을 합니다.
{ ballSpeed = 5, blockColumn = 5, blockRow = 3 };
대입 연산자로 값 복사
이제 힙에 할당된 각 구조체에 값을 채워넣어야 합니다. 그리고 그 코드는 다음과 같습니다.
arr[0] = new StageData { ballSpeed = 5, blockColumn = 5, blockRow = 3 };
위 코드를 쪼개서 살펴보면,
new StageData { ballSpeed = 5, blockColumn = 5, blockRow = 3 };
임시로 생성한 메모리 공간에 값을 채워넣은 후에 (이미 위에서 한번 설명했음)
arr[0] =
arr[0] 에 값을 대입합니다. 이 때 arr[0] 는 구조체이므로 값 복사가 일어납니다.
결과적으로 힙 메모리에 생성된 구조체 arr[0] 에 값이 채워집니다.
최종 코드
지금까지 설명한 내용을 코드로 작성하면 다음과 같습니다.
StageData[] stageDate = new StageData[5];
stageDate[0] = new StageData { ballSpeed = 5, blockColumn = 5, blockRow = 3 };
stageDate[1] = new StageData { ballSpeed = 6, blockColumn = 6, blockRow = 3 };
stageDate[2] = new StageData { ballSpeed = 7, blockColumn = 7, blockRow = 4 };
stageDate[3] = new StageData { ballSpeed = 8, blockColumn = 8, blockRow = 4 };
stageDate[4] = new StageData { ballSpeed = 9, blockColumn = 9, blockRow = 5 };
만약, 선언과 동시에 값을 초기화할 경우라면 다음과 같습니다.
StageData[] stageDate = new StageData[5]
{
new StageData { ballSpeed = 5, blockColumn = 5, blockRow = 3 },
new StageData { ballSpeed = 6, blockColumn = 6, blockRow = 3 },
new StageData { ballSpeed = 7, blockColumn = 7, blockRow = 4 },
new StageData { ballSpeed = 8, blockColumn = 8, blockRow = 4 },
new StageData { ballSpeed = 9, blockColumn = 9, blockRow = 5 },
};
정리
지금까지 구조체 배열 선언과 초기화에 대해 살펴보았습니다.
처음에는 코드가 눈에 잘 들어오지 않지만 지금까지 설명한 내용을 이해하신다면, 전체 코드가 눈에 익숙해지실 거라 생각됩니다.
'C#' 카테고리의 다른 글
물체를 목표 지점에 정확히 도착시키는 방법 (0) | 2025.07.01 |
---|---|
Visual Studio 메뉴 폰트 크기 조정 (0) | 2025.07.01 |
foreach() 순회 중 collection 변경은 예외 발생함 (0) | 2025.06.29 |
bool = 조건식 과 삼항 연산자 (0) | 2025.06.29 |
C# 의 Interface 기초부터 활용까지 (1) | 2025.06.26 |