2012-06-18 2 views
2

64 비트 우분투 리눅스에서 메모리 할당에 대해 질문하고 싶습니다.64 비트 시스템에서 메모리 할당

다음 코드를

#include <stdio.h> 
#include <string.h> 

int main(int argc, char *argv[]) { 
    char buffer_one[8], buffer_two[8]; 

    printf("Size of char: %u\n", sizeof(char)); 

    printf("Buffer_two is at %p\n", buffer_two); 
    printf("Buffer_one is at %p\n", buffer_one); 
} 

을 가지고이 실행될 때, 다음과 같은 결과가 문자 유형의 크기가 1 바이트, 심지어으로 나는 내 질문은

$ ./sizeofchar 
Size of char: 1 
Buffer_two is at 0x7fff98069910 
Buffer_one is at 0x7fff98069900 

을 가정 것으로 나타 (제발 내가 틀렸을 경우 여기에 맞습니다.) Buffer_twoBuffer_one이 서로 옆에 할당되어 있는데, 왜 Buffer_twoBuffer_one 메모리 주소는 16 바이트 떨어져 할당됩니까?

+2

이것은 엄격하게 구현 된 세부 사항입니다. 컴파일러는 임의의 주소에서 로컬 변수를 할당 할 수 있습니다. 프로그램은이 주소가 무엇인가에 의존하지 않아야합니다. –

+0

이드는 16 바이트 정렬을위한 최적화라고 생각합니다. –

+0

@Als 감사합니다.이 주소를 사용하려고하지 않습니다. 특별한 이유가 있다면 나는 궁금 할뿐입니다. – Wins

답변

6

이것은 컴파일러 종속 동작입니다. 이것들은 스택 할당 버퍼 (정말로 메모리 할당과 관련이 없습니다)이기 때문에, 스택 로컬 변수가 스택에 어떻게 배치되는지는 컴파일러가 결정합니다. 당신은 이것으로 놀 수 있지만, 모든 배열이 하나의 이유 또는 다른 이유로 16 바이트 증분으로 스택에 할당되었다고 추측 할 수 있습니다.

해체를 보면 스택 프레임에서 변수의 위치를 ​​볼 수 있습니다. 나는 char[2]char[15]이 둘 다 스택 프레임에서 16 바이트를 차지한다는 직감을 가지고 있습니다. 왜, 나는 확실하지 않다. 그러나 내가 추가 할 수있는 것은 x64 ABI이 스택이 항상 16 바이트 정렬되도록 지정하고 있으며 이러한 유형의 할당은이를 보장하기 쉽습니다.

+1

스택 포인터는'call' 명령 전에 16 바이트로 정렬되어야합니다. 왜 GCC가 스택 배열을 정렬하는지 모르겠습니다. 일부 libc 함수는 SSE에 최적화되어 있으며 16 바이트 경계에 정렬 된 데이터가 필요하지만 전역 또는 정적으로 배열 된 경우 GCC는 더 이상 정렬하지 않습니다. 또한 인텔의'icc'는 이러한 배열을 간격없이 배치합니다. 그림을 이동. –

+0

@Jonathon Reinhart 예, 당신은'char [2]'와'char [15]'에 대해 옳았습니다. 둘 다 스택 프레임에서 16 바이트를 사용하고 있습니다. 그러나 나는 또한 전역 변수들에 대해 깨닫는다, 그들은 서로 옆에 할당된다. 'char [2]'와'char [15]'의 의미있는 전역 변수에는 각각 2 바이트와 15 바이트가 할당됩니다. 왜 그런가? – Wins

+1

잘 글로벌 변수는 스택에 할당되지 않습니다. 메모리에로드 될 때 프로그램 이미지의 일부입니다. 걱정할 스택 프레임 (프레임 정렬)이 없으므로 링커는 원하는 위치에 배치 할 수 있습니다. –

관련 문제