인프런 커뮤니티 질문&답변

작성자 없음

작성자 정보가 삭제된 글입니다.

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버

RecvBuffer

ArraySegment 질문입니다

작성

·

679

1

안녕하세요 ㅎㅎ 

ArraySegment 의 신기한 점을 발견하고 질문드립니다.

Q.1 Session.cs에서 RecvBuffer 객체를 생산하고

다음과 같이  _recvArgs.SetBuffer의 인자로 WriteSegment의 반환값을 넣어주고 있습니다.

WriteSegment의 반환값이 _buffer의 값을 이용해 새로운 인스턴스를 생성했다고 생각했습니다. 왜냐면 new를 통해 만들었으까요.. 일종의 값의 복사만 일어났다고 생각을 했거든요..

근데 로직상 _recvBuffer.WriteSegment의 반환값이 RecvBuffer 객체의 맴버변수인 _buffer에도 영향을 주기에 가능하다고 생각하니 단순 값의 복사만 일어난건 아니라고 생각했습니다.

실제 테스트 해보니 _buffer를 통해 만든 newBuffer의 값을 변경하니 _buffer의 값 또한 변경됐습니다.. 이게 어찌 가능한 일인가요?

ArraySegment 생성자의 첫번째 인자가 신비로운 문제의 해답인가요?

답변 6

2

Rookiss님의 프로필 이미지
Rookiss
지식공유자

C#에서 struct = 복사, class = 참조는 맞지만
그렇다고 struct 가 무조건 스택에 올라가는 것은 아닙니다.
해당 부분은 C# 표준에 [무엇이 어떻게 되어야 한다]는 규칙은 없지만
실제로 struct 크기가 너무 커지거나, 내부적으로 참조값이 있을 경우
stack이 아닌 heap에 올라가는 것을 디버깅을 통해 확인할 수 있습니다.

답변 감사합니다!

일단 테스트를 진행했을때 struct의 사이즈를 크게 늘리면 stack overflow가 발생했던 기억이 있습니다.

개인적으로 너무 궁금한 내용이라 확인을 하고 싶어서 그러는데요.

heap으로 올라 갔다고 확신을 얻으신건 어떤 디버깅 방법을 통해서 하신건가요? IL 코드에서 확인하시는 건가요? 아니면 Windbg로 확인하시는 건가요?

선생님께서 확인하신 방법을 조금만 디테일하게 설명해 주실 수 있을까요? 앞으로도 디버깅하면서 많은 도움이 될것 같습니다.

강의 제작으로 바쁘신 와중에 번거로우시겠지만 부탁드리겠습니다! (_ _)

2

Rookiss님의 프로필 이미지
Rookiss
지식공유자

값이 복사된다는게 원본 배열 값이 복사된다는게,
아니라 ArraySegment가 복사된다는 의미였습니다.

요게 여러개 생긴다는 것입니다.

그리고 위 발언에 살짝 오류가 있는데 struct이긴 하지만
안에 참조형이 있어서 stack이 아닌 heap에 올라갑니다.
(복사되는 것은 변함없음)

1

Rookiss님의 프로필 이미지
Rookiss
지식공유자


unsafe 모드로 포인터를 이용해서 살펴본 결과입니다.
위에서 Test2나 ArraySegment 쪽 포인터를 사용하려 하면
[관리되는 형식의 포인터 주소를 사용할 수 없다]는 에러가 뜨고
실제로 스택 메모리를 살펴보는 방법도 있습니다.

답변 감사드립니다!

많은 도움이 됐습니다.

답변 주신 코드를 조금 수정해서 테스트 해봤는데요

저는 테스트에서도 struct는 Heap에 할당되지 않을것 같은 결과가 나오는것 같습니다. 

위 코드에서 Test2가 Heap에 할당됐는데, 그 멤버변수가 Stack에 할당되는건 말이 안되는것 같아요 

Rookiss님의 프로필 이미지
Rookiss
지식공유자

음 그렇군요?
[struct라도 용량이 크거나 or 참조가 있으면 힙에 올라간다]라는 정보가 많아서
별다른 테스트없이 그렇다고 알고 있었는데 위 테스트 결과를 보니 또 아닌가보군요.
버전이 바뀌면서 바뀐건지, 아니면 애당초 잘못된 사실이 와전된건지는 잘 모르겠네요.
궁금해서 stackoverflow 검색을 해보니 딱히
C# 표준에서 stack vs heap과 관련한 명확한 규칙은 없다고 합니다.
덕분에 잘못된 점을 알아갑니다 ㅎㅎ
감사합니다

저도 많이 배우고 갑니다

항상 좋은 강의 감사합니다!

0

안녕하세요~ 다른분 질문이긴 하지만 조금 이상해서 여쭤봅니다!

struct안에 참조형(class)이 있다고 해서 해당 struct가 힙에 할당되는게 맞는건가요??

struct는 스택에 할당되고, 힙에 할당된 class의 주소값만 가지고 있는게 아닌건가요??

0

답변 감사합니다.

헌데 Session#3 강의 5분 45초쯤에서 "ArraySegment는 Class가 아니라 Struct이기에 Heap이 아닌 Stack에 할당되므로 값이 복사된다." 라고 말씀하셨습니다. stack에 할당되는데 원본을 수정했을 때 같이 수정이 일어나는 이유가 무엇인가요?

0

Rookiss님의 프로필 이미지
Rookiss
지식공유자

ArraySegment는 위와 같이 데이터를 가리키고 있는 상태이지,
딱히 뭔가를 복사하는 것은 아닙니다.
말 그대로 영역을 찝어주는 역할을 하는 것이죠.
따라서 원본 데이터를 수정하면 같이 수정이 일어나게 됩니다.

작성자 없음

작성자 정보가 삭제된 글입니다.

질문하기