Różnica między dwiema kolejnymi alokacjami nie jest powiązana z przywołaniem. Twoje przydziały są tak małe, że znajdują się w segmencie danych. Libc obsługuje je wewnętrznie - przestrzeń poza swoimi bajtami sizeof int
zawiera na ogół wskaźniki do poprzedniego i następnego bloku danych oraz wielkość alokacji - w końcu po prostu free
dostanie wskaźnik i będzie musiała dowiedzieć się, ile pamięci ma do zwolnić.
Dodatkowo oba te wskaźniki są wyrównane do granicy 16-bajtowej. C11 7.22.3 mówi, że
Wskaźnik zwrócony jeśli przydział udaje się odpowiednio dostosowane tak, że może on być przyporządkowany do wskaźnik dla każdego rodzaju obiektu z podstawowym wymogiem wyrównania i umożliwia dostęp do takiego obiektu lub tablicę takich obiektów w przydzielonej przestrzeni (do momentu, gdy przestrzeń zostanie jawnie zwolniona).
Zatem nawet jeśli używasz ich do int
średnia C wymaga, aby wskaźnik wrócił być dostosowane do każdego rodzaju danych - co na wdrożenie jest 16 bajtów.
Jeśli jednak przydzielisz obiekt, który jest bardzo duży, glibc zamapuje całe strony, używając zamiast tego mmap
. Wtedy zdecydował (na moim 64-bitowa) wynosi dokładnie 16 bajtów od początku strony 4K:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a = malloc(12345678);
int *b = malloc(12345678);
printf("\n a=%p \t b=%p \n",a,b);
}
po uruchomieniu
% ./a.out
a=0x7fb65e7b7010 b=0x7fb65dbf0010
można zobaczyć mmap
połączeń z strace ./a.out
- tam wśród inny system nazywa istnieją
mmap(NULL, 12349440, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb65e7b7000
mmap(NULL, 12349440, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fb65dbf0000
Jak, dlaczego ciągle się zmienia adresy od jednej egzekucji do drugiej - jest to spowodowane address space layout randomization, or ASLR - mechanizmem bezpieczeństwa, który utrudnia złośliwym crackerom przewidywalne wykorzystanie niezdefiniowanego zachowania w kodzie.
P.S. Jeśli naprawdę potrzebujesz dynamicznie przydzielić miejsce dla 2 int
s na kolejne adresy, przydziel tablicę.
to ma znaczenie? Jeśli potrzebujesz kolejnych adresów, powinieneś używać tablicy. –
Chociaż jest to błędne, jest to interesujące pytanie. Nic więcej, możesz oczekiwać, że lokalizacje pamięci będą kolejno następujące po sobie. – Justin
Twoje adresy mają rozmiar '32' bajtów.Gdyby były kolejne, można by się spodziewać, że będą "4" bajtowe od siebie (zakładając, że 'sizeof (int) == 4', które zazwyczaj jest) – Justin