Programming/C++

Offset, 메모리 할당; ( #pragma pack | alignas | offsetof )

며용 2022. 1. 30. 21:27

윈도우 64bit 운영체제와 임베디드 운영체제 간의 메모리 기본 할당 단위가 달랐었다

▶운영체제 별로 메모리 기본 할당 단위가 다르다,,

    (64bit: 8byte / 32bit: 4byte)

 

 

offset

=> 상대 주소

기준 주소로부터 얼만큼 떨어진 곳에 원하는 데이터 값이 있다. 

고 할 때 '얼만큼 떨어진'이 offset이다

 

ex) 기준 주소: 100 일 때 +10 떨어진 곳에 위치해 있다고 하면 +10이 offset

 

 


#pragma pack()

파라그마 팩은 메모리 할당 단위를 강제로 변경시키는 define(전처리)이다

 

#pragma pack(push, 1)	//1바이트 단위로 정렬 방식을 바꾸고 기존정렬방식을 스택에 저장
struct Packing{
.
.
.
}
#pragma pack(pop)		//스택에 저장한 정렬방식을 되돌림

컴파일러는 내부에 정렬값 저장을 위한 스택을 갖고 있다

pragma pack으로 이 스택에 정렬 상태를 push, pop하며 변경할 수 있다

 

  • #pragma pack(push, n)

=> 정렬값을 n으로 변경해라

현재 상태를 저장하면서 n을 push한다. (n을 생략하면 현재 정렬값을 스택에 저장하기만 한다)

(pragma pack(): default = 8로 설정함)

 

  • #pragma pack(pop)

=> 스택 맨 위의 정렬값 꺼내기

최상단의 n값을 pop하고 그 밑의 n값으로 정렬값 변경 == 복구

 

 

- 장점

패딩 값을 없앨 수 있다

 

- 단점

데이터를 1바이트씩 읽게 되어서 성능이 느려진다

조심해서 써야한다

 

 

refer:

https://docs.microsoft.com/ko-kr/cpp/preprocessor/pack?view=msvc-170 

https://blog.naver.com/PostView.nhn?blogId=rlackd93&logNo=221967165032 

 

 


alignas()

cpp의 구조체/클래스는 정렬(alignment)만큼 크기를 갖게 된다그래서 남은 크기는 padding으로 채워지게 된다

 

alignof()	//print: alignment size
alignas()	//주소 특정 정렬(위치)로 배열
			//2의 배수여야하고 32이상 불가능, 원래 정렬보다 작은 크기 불가능

alignas(n)=> 구조체/클래스의 크기는 그대로 두고 주소를 n의 배수로 설정한다

 

 

refer:

https://en.cppreference.com/w/cpp/language/alignas

 

 

 


offsetof()

offsetof(구조체, n)

=> 말그대로 구조체 주소를 기준으로 얼만큼의 offset이 떨어져있는지 return 해준다

 

 

refer:

https://en.cppreference.com/w/cpp/types/offsetof

 

 


결국 패딩값을 없애고 싶으면 파라그마 팩 밖에 없다