메모리 정렬 에 대한 자세 한 설명
7153 단어 메모리 정렬
구조 에서 컴 파일 러 는 구조의 모든 구성원 이 자신의 자연 대 계(alignment)조건 에 따라 공간 을 분배 한다.각 구성원 은 명 시 된 순서에 따라 메모리 에 순서대로 저장 되 며,첫 번 째 구성원 의 주 소 는 전체 구조의 주소 와 같다.
예 를 들 어 아래 의 구조 각 구성원 의 공간 분배 상황(정렬 방식 이 2 바이트 이상 이 라 고 가정 하면\#pragma pack(n),n=2,4,8...다음은 토론\#pragmapack():
struct test
{
char x1;
short x2;
float x3;
char x4;
};
구조의 첫 번 째 구성원 x1 은 오프셋 주 소 는 0 으로 첫 번 째 바이트 를 차지 했다.두 번 째 멤버 x2 는 short 형식 으로 시작 주 소 는 2 바이트 가 경계 에 있어 야 합 니 다.즉,오프셋 주 소 는 2 의 배수 입 니 다.따라서 컴 파일 러 는 x2 와 x1 사이 에 빈 바이트 하 나 를 채 우 고 x2 를 오프셋 주소 가 2 인 위치 에 두 었 다.구조의 세 번 째 멤버 x3 와 네 번 째 멤버 x4 는 마침 자연 경계 주소 에 떨 어 졌 고 그 앞 에 추가 로 바 이 트 를 채 울 필요 가 없다.test 구조 에서 구성원 x3 는 4 바이트 대 계 를 요구 하고 이 구조의 모든 구성원 중에서 요구 하 는 최대 대 계 유닛 이기 때문에 test 구조의 자연 대 계 조건 은 4 바이트 이 고 전체 구조 체 의 크기 는 최대 대 계 유닛 크기 의 정수 배(구조 체 내부 에 구조 체 가 있 을 때 도 이 규칙 을 따른다.다음 에 언급 할 것 이다)이 며 컴 파일 러 는 구성원 x4 뒤에 3 개의 빈 바이트 를 채 웠 다.전체 구조 가 차지 하 는 공간 은 12 바이트 이다. 메모리 정렬 을 왜 하 는 지 에 대해 서 는<메모리 정렬 분석 Data alignment:Straighten up and fly right 에 대한 자세 한 설명>를 참고 하 십시오.이 문장 을 보면 아래 의 내용 을 더욱 쉽게 이해 할 수 있다.자,다음은#pragma pack:
2.#pragma pack()
이 예비 처리 명령 은 정렬 파 라 메 터 를 바 꾸 는 데 사용 된다.부족 한 상황 에서 C 컴 파일 러 는 모든 변수 나 데이터 유닛 으로 자 연 스 럽 게 경계 조건 에 따라 공간 을 분배 합 니 다.일반적으로 다음 방법 을 통 해 결 성 된 정렬 매개 변 수 를 바 꿀 수 있 습 니 다.
위 명령 을 사용 하여\#pragma pack(n),C 컴 파 일 러 는 n 바이트 로 정렬 합 니 다.
/가짜 명령 을 사용 하여\#pragma pack(),사용자 정의 바이트 정렬 방식 을 취소 합 니 다.
다음 과 같이 쓸 수도 있다.
#pragma pack(push,n)
#pragma pack(pop)
\#pragma pack(n)은 각 구성원 의 정렬 단원 이 n(n 이 2 인 정수 차 멱)보다 크 지 않다 는 것 을 나타 낸다.여기 서 규정 한 것 은 상계 이 고 정렬 단원 이 n 보다 큰 구성원 에 게 만 영향 을 주 며 정렬 바이트 가 n 보다 크 지 않 은 구성원 에 게 는 영향 을 주지 않 습 니 다.사실 말 그대로 pack 은'소포,포장'이라는 뜻 입 니 다.\#pragma pack(n)은 n 개의 바이트 가'소포'라 고 규정 하고 있 습 니 다.개인 적 으로 이해 하지 못 하면 프로세서 가 메모리 에서 n 개의 바이트 를 한꺼번에 읽 거나 쓸 수 있다 고 생각 할 수 있 습 니 다.이렇게 이해 하기 쉽 습 니 다.n 보다 작은 멤버 에 게 는 당연히 자신의 정렬 조건 에 따라 정렬 해 야 한다.아무리 넣 어도 한꺼번에 꺼 낼 수 있 기 때문이다.n 개의 바이트 보다 정렬 조건 이 큰 구성원 에 게 구성원 은 자신의 정렬 조건 에 따라 정렬 하고 n 바이트 에 따라 정렬 하 는 데 똑 같은 읽 기 횟수 가 필요 하지만 n 바이트 에 따라 공간 을 절약 하 는 것 이 좋 겠 습 니까?내 가 위 에서 언급 한<메모리 정렬 분석 Data alignment:Straighten up and fly right 에 대한 자세 한 설명>를 참고 할 수 있다.다음은 큰 소의 관점 입 니 다.저 에 게 말 한 것 은 다음 과 같은 뜻 입 니 다.
All it means is that each member of it will require alignment no greater than n.It doesn't mean that each member will have alignment requirement n.Notice, after all, it's called pack and not align for a reason-- precisely because it controls packing, not alignment.
또한 GNU C 는 다음 과 같은 방식 도 있다.
・ __attribute__((aligned(n)))는 역할 을 하 는 구조 구성원 을 n 바이트 자연 경계 에 맞 춥 니 다.구조 에 멤버 의 길이 가 n 보다 크 면 최대 멤버 의 길이 에 따라 정렬 합 니 다.
・ __attribute__ ((packed))구조 가 컴 파일 과정 에서 의 최적화 정렬 을 취소 하고 실제 점용 바이트 수 에 따라 정렬 합 니 다.
이상 의 n=1,2,4,8,16...첫 번 째 방식 은 비교적 흔히 볼 수 있다.
3.구조 체 내 구성원 은 자신의 위 치 를 어떻게 찾 는가
먼저 다음 과 같은 규칙 을 따른다.
1. 각 구성원 은 각각 자신의 정렬 방식 과\#pragma pack 이 지정 한 정렬 매개 변수 두 사람의 작은 값 을 자신의 정렬 방식 으로 합 니 다.
2. 복잡 한 유형(예 를 들 어 구조)의 정렬 방식 은 이 유형 이 성명 할 때 사용 하 는 정렬 방식 이거 나 성명 할 때 모든 구성원 이 사용 하 는 정렬 매개 변수의 최대 값 입 니 다.마지막 으로 이때 의\#pragma pack 이 지정 한 정렬 매개 변수 와 극소 값 을 가 집 니 다.큰 소 는 이렇게 말 했다.
The documentation for #pragma pack(n) says that "The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member,whichever is smaller". However I think this is incorrect; the docs should say that the alignment of a member will be on a boundary that is either a multiple of n or the alignment requirement of the member, whichever is smaller.
3. 정렬 후의 길 이 는 구성원 중 가장 큰 정렬 매개 변수(구성원 의 크기 가 아 닌)의 정수 배 여야 합 니 다.이렇게 하면 배열 을 처리 할 때 모든 항목 이 경계 정렬 을 보장 할 수 있 습 니 다.
4. 배열 에 대해 예 를 들 어 char a[3];이것 은 정렬 방식 과 각각 3 개의 char 를 쓰 는 것 과 같다.그 러 니까 한 바이트 로 맞 추 는 거 야.
쓰 면:typedef char Array 3[3];
Array 3 같은 유형의 정렬 방식 은 길이 가 아 닌 한 바이트 로 정렬 합 니 다.
5. 유형 이 무엇이든 정렬 된 경 계 는 1,2,4,8,16,32,64...중 하나 입 니 다.
간단 한 예 를 보 자.
#pragma pack(8)
struct s1
{
short a;
long b;
};
struct s2
{
char c;
s1 d;
long long e;
};
#pragma pack()
구성원 정렬 에는 중요 한 조건 이 있 습 니 다.각 구성원 이 각각 정렬 합 니 다.즉,모든 구성원 이 자신의 방식 대로 정렬 하 는 것 이다.위 에서 8 바이트 로 정렬 하도록 지 정 했 지만 모든 멤버 가 8 바이트 로 정렬 하 는 것 은 아니 라 는 것 이다.정렬 규칙 은 각 구성원 이 그 유형의 정렬 매개 변수(보통 이 유형의 크기)와 지정 한 정렬 매개 변수(여 기 는 8 바이트)중 작은 정렬 입 니 다.또한 구조의 길 이 는 사용 한 모든 정렬 매개 변수의 정수 배(최대 정렬 매개 변수의 정수 배 만 있 으 면 된다)이 어야 하 며 부족 하면 빈 바이트(컴 파일 러 에 따라 정 해진 다)를 보충 해 야 한다.
S1 에서 구성원 a 는 2 바이트 로 기본적으로 2 바이트 로 정렬 하고 정렬 매개 변 수 를 8 로 지정 합 니 다.이 두 값 에서 2 를 취하 고 a 는 2 바이트 로 정렬 합 니 다.멤버 b 는 4 개의 바이트 입 니 다.기본 값 은 4 바이트 로 정렬 합 니 다.이 때 는 4 바이트 로 정렬 합 니 다.a 는 2 개의 바 이 트 를 보충 한 후에 b 를 저장 하기 때문에 sizeof(S1)는 8 이 어야 합 니 다.8 은 4 의 배수 로 상술 한 제3 조 규칙 을 만족시킨다.
S2 에서 c 는 S1 의 a 와 마찬가지 로 2 바이트 로 정렬 하고 d 는 구조 입 니 다.8 바이트 입 니 다.무엇 에 따라 정렬 합 니까?구조 적 으로 기본 정렬 방식 은 이 구조 정의(성명)를 사용 할 때 모든 구성원 이 사용 하 는 정렬 매개 변수 중 가장 큰 것 입 니 다.S1 은 4 로 지정 한 8 보다 작 습 니 다.그래서 멤버 d 는 4 바이트 로 정렬 하고 c 후 2 바이트,뒤 에는 8 바이트 의 구조 체 d 입 니 다.멤버 e 는 8 개의 바이트 입 니 다.기본적으로 8 바이트 로 정렬 되 어 있 습 니 다.지정 한 것 과 같 기 때문에 8 바이트 의 경계 에 맞 추 었 습 니 다.이때 12 개의 바이트 가 사용 되 었 기 때문에 d 후에 4 개의 바이트 를 추가 하고 16 번 째 바이트 부터 멤버 e 를 배치 합 니 다.이때 길 이 는 24 로 최대 정렬 매개 변수 8(구성원 e 는 8 바이트 로 정렬)에 의 해 정 제 될 수 있 습 니 다.이렇게 해서 모두 24 개의 바이트 가 사용 되 었 다.
위의 것 은 복잡 하지 않 습 니까?하나 더:
#pragma pack(4)
struct s1
{
char a;
double b;
};
#pragma pack()
#pragma pack(2)
struct s2
{
char c;
struct s1 st1;
};
#pragma pack()
#pragma pack(2)
struct s3
{
char a;
long b;
};
#pragma pack()
#pragma pack(4)
struct s4
{
char c;
struct s3 st3;
};
#pragma pack()
s1 을 먼저 보고 a 는 오프셋 주소 가 0 인 위치(첫 번 째 바이트)에 놓 습 니 다.b.기본 8 바이트 정렬 이지 만 정렬 매개 변 수 를 4 바이트 로 지정 하기 때문에 b 는 4 바이트 로 정렬 하고 오프셋 주소 가 4 인 위치 에 두 고 a 후 3 개의 바이트 를 보충 합 니 다.그래서 sizeof(s1)는 12 입 니 다.구조 체 s1 의 정렬 매개 변 수 는 4 이 며 아래 에 사 용 됩 니 다.s2,c 를 첫 번 째 바이트 에 놓 으 세 요.st1 자신의 정렬 매개 변 수 는 4 이지 만 이때 지정 한 정렬 매개 변 수 는 2 이기 때문에 st1 은 2 바이트 에 따라 정렬 하고 c 후 하나의 바이트 를 보충 한 후에 st1 을 저장 합 니 다.주의 하 세 요.st1 내 부 는 변 하지 않 습 니 다.s1 이 어떻게 되 는 지 설명 할 때 어떻게 되 는 지,왜냐하면 우 리 는 sizeof(s2.st1)=sizeof(s1)를 보증 해 야 하기 때 문 입 니 다.그렇지 않 으 면 혼 란 스 럽 습 니 다.이렇게 sizeof(s2)는 14 입 니 다.구조 체 s2 의 정렬 매개 변 수 는 2,14 는 2 의 정수 배 이다.
s3,a 를 첫 번 째 바이트 에 놓 으 세 요.b.기본 4 바이트 정렬 이지 만 지정 한 정렬 매개 변 수 는 2 입 니 다.그래서 b 는 2 바이트 로 정렬 하고 오프셋 주소 가 2 인 위치 에 두 고 a 후에 바이트 하 나 를 추가 합 니 다.sizeof(s3)는 6 입 니 다.구조 체 s3 의 정렬 매개 변 수 는 2(뒤에 사용)이 고 6 은 2 의 정수 배 이다.
마지막 으로 s4,c 를 첫 번 째 바이트 에 놓 습 니 다.st3 자신의 정렬 매개 변 수 는 2 이 고 지정 한 정렬 매개 변 수 는 4 이기 때문에 st3 는 극소 값 을 취하 고 2 바이트 로 정렬 하여 오프셋 주소 가 2 인 위치 에 두 고 c 후에 바이트 하 나 를 추가 합 니 다.sizeof(s4)는 8 이 고 구조 체 의 정렬 매개 변 수 는 2,8 은 2 의 정수 배 이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
메모리 정렬 에 대한 자세 한 설명\#pragma pack(n)은 각 구성원 의 정렬 단원 이 n(n 이 2 인 정수 차 멱)보다 크 지 않다 는 것 을 나타 낸다.여기 서 규정 한 것 은 상계 이 고 정렬 단원 이 n 보다 큰 구성원 에 게 만 영...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.