[C#] Struct에서의 NEW 키워드

RisingJade의 개발기록·2022년 3월 9일
0

Struct에서의 NEW

이미 존재하는 인스턴스를 참조하지 않는이상 참조타입으로 선언된 변수를 사용하기 위해선 반드시 할당을 해야한다.

SampleClass SC = new SampleClass(100);

보통 이런식으로 new 를 통해 운영체제에 의해 공간을 할당받아 생성되는 인스턴스는 힙(Heap)영역에 올라가게 된다.

반대로 struct 타입으로 선언된 변수는 일반 변수처럼 선언하되, 멤버변수들을 초기화 하기만 하면 new 를 통한 할당없이도 사용할 수 있습니다. ( 일반 변수들과 사용하는 것이 비슷하다.)

//아래와 같이 사용할 경우 멤버를 모두 초기화해주기 전에는 사용할 수 없다. 상당히 귀찮다.
SampleStruct SS;
SS.a = 1;
SS.b = 2;
SS.c = 3;
SS.Test();

다만 struct를 쓰기에는 c++에 비해서는 불편한게 기본 생성자를 사용할 수 없고(무지성 선언 불가...) 선언 후 이를 사용할려면 멤버를 모두 초기화 해야하며 클래스로 부터의 상속을 사용할 수 없고(인터페이스는 가능) 불변성을 띄는경우가 있다 등등의 별의 별제약사항이 있다.

  • 그래서 new 키워드로 그냥 생성하는 경우가 생겼다...
//3가지 멤버를 한번에 초기화 해주는 생성자를 호출한다. 훠어얼씬 편함
SampleStruct SS = new SampleStruct(1,2,3);
  • 이때...! C/C++ 적인 관점에서 보면 new로 초기화를 했으니 힙영역에 있겠지?라고 생각하겠지만

    놀랍게도 MS공식 레퍼런스에 따르면 STACK영역에 있다.

  • 단! class 내부에 존재하는 struct는 당연히 클래스 동적할당시 올라가는 힙영역에 같이 올라간다.
class StructTest
    {
        int a;
        SampleStruct SS; //이부분이 스택에 올라가는건 아니다.
    }
main(){
	StructTest test1 = new StructTest(); //이런식으로 클래스가 동적할당으로 heap에 올라가면 SampleStruct도 같이 힙으로간다.
}
    
  • 부록, 출처에 가보시면 더 잘 설명되있습니다.

"Struct의 사용은 일반적으로는 힙 메모리의 동적 할당을 하지 않기때문에 속도면에서 빠르다고 볼 수 있습니다.
다만 대입이나 값의 전달과 관련된 부분에 대해서는 다시 생각해볼 필요가 있습니다.
C#에서 Class 타입은 경우 참조 타입(Reference Type) 이기때문에 서로 단순 대입을 할때는 레퍼런스 값만 복사(참조 복사)가 일어납니다. 이는 내부적으로 포인터로 구현되어 있을 것이며 4바이트 값의 복사만 일어납니다. (한번에 복사가 가능합니다.)
다만 값 타입(Value Type)인 Struct 타입의 경우 일반적으로 서로 단순 대입을 할때는 메모리 값 자체의 복사가 일어납니다. 이것이 한번에 일어나면 좋겠으나 한번 복사할 수 있는 양은 정해져 있습니다. 따라서 일정 바이트크기를 넘어간 데이터의 메모리 값 복사가 일어날때는 반복적으로 복사가 일어나기 때문에 여기에 시간이 소모될 수 있습니다.
(하필 이런 값타입끼리의 단순 대입이나 값전달 코드들은 개발하다 보면 매 루프마다 호출된다던지 등등 굉장히 흔하게 호출되곤 합니다.).Net에서는 이전버전에서는 16바이트 현 버전에서는 약 24~26바이트 정도 까지 한번에 복사가 가능 하므로 구조체의 크기가 이보다 훨씬 더 커지는 경우 메모리 값 복사에 다소 신경 쓸 필요가 있습니다. C++의 경우 이런 거대한 데이터를 전달해야할 상황일때 포인터로 전달하는 방법이 있겠으나 C#은 일반적으론 거대한 Struct를 전달 하는 경우에 대한 마땅한 해결책이 없습니다. 따라서 가급적 Struct는 크지않은 데이터에 대해서 사용하는 편이 좋습니다."

출처: https://asta8080.tistory.com/5

profile
언제나 감사하며 살자!

0개의 댓글