2013-07-06 3 views
1

이 32 비트 주소를 반환하는 동안 mmap()이 64 비트 주소를 반환하는 이유는 무엇입니까?mmap() 대 malloc() 반환 주소

char *a = (char *)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 
printf("%p\n", a); // example: 0x7fbfbb065000 

char *b = (char *)malloc(10); // example: 0x23bf010 
printf("%p\n", b); 
+2

당신은 반환을 캐스팅 할 필요가 없습니다 C 프로그램에서 'malloc'(또는'mmap')의 값. –

+1

이것은 완전히 구현에 종속적이며 흥미롭지 않습니다. –

+0

이득을 얻고 다시 확인하십시오 –

답변

1

커널은 메모리 힙을 하위 4GB에 배치하므로 malloc (3)은 상위 32 비트를 모두 지운 64 비트 주소를 반환합니다.

코드 끝에서 잠자기를 추가하고 &을 다시 컴파일하면 프로그램을 다시 실행할 수 있습니다. 그런 다음 "/ proc 디렉토리/PROCESS_ID /지도"읽고, 힙이 낮은 4기가바이트에있는 것을 볼 수 있습니다 :

퍼센트 고양이/PROC/26375 /지도

 
00400000-00401000 r-xp 00000000 ca:01 46177        /root/c/a.out 
00600000-00601000 r--p 00000000 ca:01 46177        /root/c/a.out 
00601000-00602000 rw-p 00001000 ca:01 46177        /root/c/a.out 
01e03000-01e24000 rw-p 00000000 00:00 0         [heap] 
7f654038c000-7f6540541000 r-xp 00000000 ca:01 395503      /lib/x86_64-linux-gnu/libc-2.15.so 
7f6540541000-7f6540740000 ---p 001b5000 ca:01 395503      /lib/x86_64-linux-gnu/libc-2.15.so 
7f6540740000-7f6540744000 r--p 001b4000 ca:01 395503      /lib/x86_64-linux-gnu/libc-2.15.so 
7f6540744000-7f6540746000 rw-p 001b8000 ca:01 395503      /lib/x86_64-linux-gnu/libc-2.15.so 
7f6540746000-7f654074b000 rw-p 00000000 00:00 0 
7f654074b000-7f654076d000 r-xp 00000000 ca:01 395517      /lib/x86_64-linux-gnu/ld-2.15.so 
7f6540960000-7f6540963000 rw-p 00000000 00:00 0 
7f654096a000-7f654096d000 rw-p 00000000 00:00 0 
7f654096d000-7f654096e000 r--p 00022000 ca:01 395517      /lib/x86_64-linux-gnu/ld-2.15.so 
7f654096e000-7f6540970000 rw-p 00023000 ca:01 395517      /lib/x86_64-linux-gnu/ld-2.15.so 
7fff4445e000-7fff4447f000 rw-p 00000000 00:00 0       [stack] 
7fff44500000-7fff44501000 r-xp 00000000 00:00 0       [vdso] 
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0     [vsyscall] 
0

시스템에 64 비트 포인터가 있으면 둘 다 64 비트 주소를 반환합니다. malloc은 맨 위의 32 비트가 0으로 설정되어 있기 때문에 발생합니다. 이유는 구현에 완전히 의존하고 있습니다. 질문에 linux 태그가 지정되어 있기 때문에 소스를 조사해 보면 알 수 있습니다.

2

이것은 실제로 malloc()mmap() 구현의 구현 세부 사항입니다. 할당 크기를 16 MiB로 변경하면 mmap()malloc()과 매우 유사한 결과가 나타납니다. 두 개의 시스템 중 하나가 호출에서 유닉스 시스템에서

, 할당 된 메모리는 일반적으로 온다 : sbrk()mmap(), 그래서 malloc() 구현은 일반적으로 두 함수 중 하나를 호출합니다. malloc() 함수는 시스템 콜이 아닌 라이브러리 함수입니다 (설명은 섹션 3에있는 이유 설명이며 sbrk()mmap()은 섹션 2에 있습니다).

예제에서 10 바이트와 같이 작은 할당의 경우 일반적으로 malloc()은 많은 할당을 하나의 큰 할당으로 그룹화하고 일부 구현은 sbrk()을 사용합니다. 예제에서 16 MiB와 같은 큰 할당의 경우 malloc()mmap()을 호출하고 완료합니다.