내 컴퓨터 에서이 코드를 컴파일 한 후 이상한 것을 발견했습니다.
#include <stdio.h>
int main()
{
printf("Hello, World!\n");
int a,b,c,d;
int e,f,g;
long int h;
printf("The addresses are:\n %0x \n %0x \n %0x \n %0x \n %0x \n %0x \n %0x \n %0x",
&a,&b,&c,&d,&e,&f,&g,&h);
return 0;
}
결과는 다음과 같습니다. 모든 int 주소 사이에는 4 바이트의 차이가 있습니다. 그러나 마지막 int와 long int 사이에는 12 바이트 차이가 있습니다.
Hello, World!
The addresses are:
da54dcac
da54dca8
da54dca4
da54dca0
da54dc9c
da54dc98
da54dc94
da54dc88
답변
12 바이트는 걸리지 않았지만 8 개만 걸렸습니다. 그러나이 플랫폼에서 8 바이트 길이 int 의 기본 정렬 은 8 바이트입니다. 따라서 컴파일러는 long int를 8로 나눌 수있는 주소로 이동해야했습니다. “분명한”주소 da54dc8c는 8 바이트로 나눌 수 없으므로 12 바이트 간격이 아닙니다.
이것을 테스트 할 수 있어야합니다. long 전에 다른 int를 추가하여 8 개가 있으면 long int가 이동하지 않고 정렬됩니다. 이제 이전 주소에서 8 바이트 밖에되지 않습니다.
이 테스트가 작동하더라도 이러한 방식으로 구성되는 변수에 의존해서는 안된다는 점을 지적 할 가치가 있습니다. AC 컴파일러는 변수 정렬 순서를 포함하여 프로그램을 신속하게 실행하기 위해 모든 종류의 펑키 작업을 수행 할 수 있습니다 (일부 경고 사항 포함).
답변
컴파일러가 변수 사이에 추가 패딩을 생성하여 메모리에 올바르게 정렬되도록하기 때문입니다.
대부분의 최신 프로세서에서 값에 여러 크기의 주소가 있으면 값에 액세스하는 것이 더 효율적입니다. 이 두었다면 h
가능한 첫 번째 자리에, 그 주소는 8의 배수가 아닌, 그래서 사용에 덜 효율적이었을 0xda54dc8c했을 것이다. 컴파일러는 이것에 대해 알고 있으며 마지막 두 변수 사이에 약간의 사용되지 않은 공간을 추가하여 발생하는지 확인합니다.
답변
이 지역 변수의 주소를 서로 관련시키는 데 언어가 필요하지 않기 때문에 테스트는 반드시 생각한 것을 테스트하지는 않습니다.
스토리지 할당에 대해 무언가를 추론하려면 구조체에 필드로 필드를 넣어야합니다.
지역 변수는 특정 방식으로 서로 옆에 스토리지를 공유 할 필요가 없습니다. 예를 들어, 컴파일러는 스택 내의 임의의 위치에 임시 변수를 삽입 할 수 있습니다 (예 :이 두 로컬 변수 사이에있을 수 있음).
반대로, 임시 변수를 구조체에 삽입 할 수 없으므로 구조체 필드의 주소를 대신 인쇄하면 동일한 논리적 메모리 척 (구조)에서 할당 된 항목을 비교하게됩니다.