Written on
·
390
1
stack에서 mage는 struct구조체로 복사하여 사용하고
mage와 mage2는 각각 다른 본체라서 서로 hp가 다르게 나온다.
knight2.hp = knight
knight.hp = 0
으로 kinght의 hp와 knight2의 hp를 서로 다르게 할려했지만 heap의 같은 본체의 주소를
사용하기때문에 kinght의 hp도 똑같이 0이 되어버렸고,
Knight knight = new Kinght() 로 했을때는 heap에서 새로운 영역을 할당받아서
knigh2라는 heap의 새롭게 만들어진 영역의 본체주소를 사용해서
knight와 knight2 라는 각각 다른 개체를 만들수 있었다
라는게 제가 이해한 내용인데
그럼 mage와 mage2는 heap에는 아무런 영역이 없고
stack내에서만 사용되는 각각의 본체가 맞는지 궁금합니다.
Answer 1
4
안녕하세요, 이해하신 내용이 맞습니다.
C++과 다르게 C#의 경우 struct는 값(복사) 형식이라서
그냥 사용할 경우 스택 영역에 직접 데이터가 들어갑니다.
(여기서 '그냥'이라 하는 이유는, struct이라도 class 내에 정의된 멤버 변수로 사용하면
class의 new를 하는 순간 같이 딸려서 heap에 올라가기 때문입니다)
2020/10/07 업데이트:
게임 서버 시간에 질문이 나와 상세 내용 추가 합니다.
struct 크기가 엄청 크거나, 내부적으로 참조 값 등을 갖고 있을 때 등 특정 경우에는
struct 도 Heap에 올라갈 수도 있습니다!
~다만 정확한 규칙은 MS 구현 스펙에 의존적이라 우리가 크게 신경쓸 내용은 아닙니다.
반면 C#의 class는 참조 형식이고, C++로 치면 무조건 포인터(*)를 사용하는 셈이 됩니다.
따라서 knight = new Knight()을 하면, 힙에는 실제 원본 데이터가 있는 메모리가 할당되고
knight 변수에는 해당 원본 주소를 들고 있게 됩니다.
이해를 돕기 위해 아래 스샷을 첨부합니다.
r1의 경우 스택 영역에 id, size가 실제로 들어가 있지만,
r2의 경우 힙 주소를 들고 있고 실제로 그 주소를 타고 가보면 근처에 원본 데이터가 있는 것을 알 수 있습니다.