sizeof 연산자는 컴파일러가 컴파일할때 크기를 인식한다. 그 크기를 상수로 바꾼다.
포인터를 동적할당한뒤 sizeof을 하면 배열을 sizeof한것과 달리 포인터의 크기만 나오게 된다.

클래스의 크기

컴파일러가 빈 클래스를 보면, 더미 맴버를 안에 넣어서 생성하게 된다.

1
2
3
4
5
6
7
class A {};

becomes:

struct A {
char __dummy;
};

빈 껍데기를 상속받은 클래스도 base class optimization을 수행하는 대부분의 컴파일러에서는 1 바이트가 된다.

Case 1. Empty Class 크기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Temp
{};

// Temp Size = 1

class CBase // Size = 1
{
public:
CBase(){}
~CBase() {}
void Test() {}
};

class CSub : public CBase // Size = 1
{
public:
CSub(){}
~CSub(){}
};

Case 2. 가상함수가 있는 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class CVBase  // Size = 4
{
public:
CVBase() {}
~CVBase() {}
void Test() {}

virtual void Func1(){}
virtual void Func2(){}
virtual void Func3(){}
};

class CVSub1 : public CVBase // Size = 4
{
public:
CVSub1(){}
~CVSub1(){}
};

class CVSub2 : public CVBase // Size = 4
{
public:
CVSub2(){}
~CVSub2(){}

virtual void Func1() {}
virtual void Func2() {}
virtual void Func3() {}
};

class CVSub3 : public CVBase // Size = 4
{
public:
CVSub3() {}
~CVSub3(){}

void Func1(){}
void Func2(){}
};

Case 3. Static 맴버 변수가 있는 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class CSObject  // Size = 1
{
public:
static int _x;
static int _y;

};

class CSVObject : public CSObject // Size = 12
{
public:
int _a;
int *b;
char c;

};

빈 클래스인 경우, 메모리 상에서 Instance 들이 Array에서 Empty Class의 Instance를 구분하기 위해서 최소한의 크기인 1byte를 할당.
Class의 Instance는 Heap or Stack 어딘가에 자리를 잡을수 있게 되고, Class Instance를 구분할수 있게 주소를 받게된다.

가상함수가 사용된다면 가상함수테이블를 가르키는 포인터가 클래스 내부안에 들어가게 되므로, 4 바이트 할당된다.
static 변수는 Class안에 있는것 처럼보이지만, 해당 클래스에 하나만 생성되고 모든 인스턴스에서 공동으로 접근가능하므로,
실제로는 안에 있지가 않다.

클래스와 구조체는 Default Access의 차이밖에 없다. 즉, 맴버변수에 따라서, Padding이 일어나는데, 가장 큰변수를 타입으로 저장하게 된다.
위의 예제는 int가 가장크므로 sizeof(int) * 3과 같게된다.

배열, 포인터의 전달과 크기

1
2
3
4
5
6
7
8
9
10
11
12
13
int SIZE_p(int *p)
{
return sizeof(p);
}
int SIZE_a(int a[])
{
return sizeof(a);
}

int Array[] = { 1,2,3,4,5 };
printf("%d\n", sizeof(Array)); // 4 * 5 = 20
printf("%d\n", SIZE_p(Array)); // Pointer 명시적 전달 4
printf("%d\n", SIZE_a(Array)); // Pointer 암묵적 전달 4