본문 바로가기

프로그래밍/기본지식

메모리 할당 정렬 #pragma pack

컴파일러에선 기본적으로 4바이트 단위로 메모리를 엑세스하기위해 메모리 공간을 할당해준다. 
예를 들어 
struct _Unpacked
{
	char a;
	char b;
	int e;
};

아무런 처리도 안한 VC컴파일러에서 위 구조체는 몇바이트로 출력되겠는가
아마도 바이트 수대로라면 32bit 운영체제 기준으로 char 2개 2바이트 int 1개 4바이트
2+4 = 6바이트 일것이다.

void main()
{
	printf("sizeof : %d\n",sizeof(_Unpacked));
}

하지만 실제로 sizeof를 이용해 출력해보면 출력결과는 "sizeof : 8"이다. 
VC에서 int 형에 맞춰 4바이트 단위로 메모리를 할당했기때문이다.
이렇게 정렬되지 않은 메모리는 바이너리 단위를 주고받는 네트워크 프로그래밍이선 문제가 될수있다. 
이럴땐 #pragma pack을 사용하면된다.

#pragma pack(push,1)
struct packed
{
	char a;
	char b;
	int e;
};
#pragma pack(pop)

#pragma pack(push,1)의 의미는 이 아래부터 정의되는 것은 메모리상에서 1바이트 단위로 정렬되어 할당된다는 뜻이다.
그리고 정의가 끝나면 #pragma pack(pop)을 이용해 끊여줘야 한다.
안그러면 1바이트 단위의 정렬이 필요없는 곳까지 정렬이되어 메모리 엑세스 속도가 느려져 성능이 저하될수도 있다.
#include<stdio.h>
#pragma pack(push,1)
struct packed
{
	char a;
	char b;
	int e;
};
#pragma pack(pop)
struct _Unpacked
{
	char a;
	char b;
	int e;
};
void main()
{
	printf("sizeof : %d\n",sizeof(packed));
	printf("sizeof : %d\n",sizeof(_Unpacked));
}

실행결과
sizeof : 6
sizeof : 8