Total Articles 494
MyObject라는 클래스가 있습니다.
class MyObject { char buf[0x100]; }
MyObject 클래스는 내부적으로 0x100 바이트(256)를 가지고 있는 클래스입니다. 이 클래스의 객체를 함수 내에 선언을 하게 되면 stack에 0x100 바이트를 할당받아야 하겠죠.
다음 코드를보면 obj1, obj2, obj3 3개의 객체가 있습니다. 3개의 객체가 언제 stack에 할당이 될까요?
void test1() { MyObject obj1; { MyObject obj2; { MyObject obj3; } } }
상기 코드에 대한 Assembly 결과입니다.
; 8 : { push ebp mov ebp, esp sub esp, 776 ; 00000308H ; 9 : MyObject obj1; ; 10 : { ; 11 : MyObject obj2; ; 12 : { ; 13 : MyObject obj3; ; 14 : } ; 15 : } ; 16 : }
Assembly 코드를 보면 3개 객체를 위한 stack상에서의 메모리 할당은 함수가 시작되는 시점은 각각 block이 시작되는 위치가 아니라, 함수의 진입 시점에서 한꺼번에 할당이 되어 짐을 알 수가 있습니다(300H가 아니고 308H가 된 것은 약간의 prologue/eplogue에 필요한 정보가 추가된 것임). 정리를 하자면
block 내부에 선언되는 local object의 stack 할당은 block 내부에 진입하는 시점이 아니라 function의 prolog code에서 한꺼번에 할당이 된다.
가 되겠습니다.
컴파일 : Microsoft Visual Studio 2008 Release mode Code Optimization - Disabled(/Od)
다운로드 : block_test.zip
block을 N번 반복한다고 가정을 하고 constructor, assign operator, destructor가 몇번씩 실행되는지 정리해 보았습니다.
constructor
assign
destructor
while(true)
{
MyObject obj; /* nullary constructor */
...
}
N
N
while(true)
{
MyObject obj; /* non-nullary constructor */
obj = "foo"; /* assign-operator */
...
}
N
N
N
while(true)
{
MyObject obj = "foo"; /* non-nullary constructor */
...
}
N
N
MyObject obj;
while(true)
{
obj = "foo"; /* assign-operator */
...
}
1
N
1
stack 구성은 모두 동일하게 됨.
int, char와 같은 primitive type은 상관이 없지만, string과 같이 constructor, destructor가 있는 class이라면 for문 바깥에서 선언을 해 주는 것이 성능면에서 좋다.