#include <iostream>
using namespace std;
struct ST {
long a;
int b;
short c;
}
int main() {
cout << sizeof(ST) << '\n';
return 0;
}
의 경우 long = 8bytes, int = 4bytes, short = 2bytes이므로 14bytes로 예상하지만
결과는 16bytes가 나온다.
이는 memory access pattern때문에 컴파일러가 알아서 사이에 paddding을 넣어준다.
memory access pattern
struct ST {
char c1;
int i4a;
int i4b;
double d8;
}
의 경우
c1 1bytes는 그냥 들어간 뒤 4의 배수로 밖에 들어갈 수 없는 int를 위해 3bytes padding이 생기고
int들은 그대로 4의 배수로 4bytes씩 들어간 뒤
double은 8bytes로 8의 배수로 밖에 memory allocation을 할 수 없으므로 8의 배수인 16을 만들기 위해 4bytes padding을 주고 8bytes가 들어가서
총 24bytes크기의 구조체가 된다.
CPU의 캐시라인
#include <iostream>
class Cat
{
public:
void printCat();
private:
int age;
int weight;
};
int main()
{
Cat cat1;
Cat cat2;
Cat * catPtr = &cat1;
std::cout << sizeof(catPtr) << std::endl;
return 0;
}
라고 할 경우
int가 2개이므로 구조체의 크기는 8bytes라고 생각할 수도 있고
멤버함수 printCat()가 있으므로 이 함수를 가르키는 포인터가 생겨 이 포인트를 저장하기 위해 8bytes가 추가되어 구조체의 크기는 16bytes라고 생각할 수도 있다.
답은 8bytes로 함수는 구조체 크기에 영향을 미치지않는다.
64bits환경에서 포인터는 type에 상관없이 항상 8bytes를 갖는다(64bits = 8bytes이므로 주소 표현시 8bytes)