兩個連續分配之間的差距與尋呼無關。您的分配太小以至於它們駐留在數據段中。 Libc在內部處理這些內容 - sizeof int
字節之外的空間通常包含指向前一個和下一個數據塊的指針以及分配的大小 - 畢竟free
只會得到一個指針,並且需要計算出它有多少內存解除分配。
此外這兩個指針都對齊到16字節的邊界。 C11 7.22.3說
指針返回如果分配成功,則適當地對準,使得其可被指派給的指針的任何類型的物體,其一個基本對齊要求然後用於訪問這樣的對象或分配空間中的這樣的對象的數組(直到空間被明確地解除分配)。
因此,即使你使用它們int
C標準要求指針返回任何數據類型保持一致 - 這對你的代碼是16個字節。
但是,如果您分配了一個非常大的對象大,則glibc將使用mmap
來代替整個頁面。然後對齊(我的64位計算機上)是從4K頁的開始正好是16個字節:
#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);
}
運行
% ./a.out
a=0x7fb65e7b7010 b=0x7fb65dbf0010
一個時可以看到mmap
電話與strace ./a.out
- 有中其他系統調用有
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
至於爲什麼地址不斷變化從一個執行到另一個 - 這是由於address space layout randomization, or ASLR - 一個安全機制,這使得它更難以在您的代碼中使用利用未定義的行爲。
P.S.如果您確實需要爲連續地址動態分配空間,請分配一個數組。
什麼關係呢?如果你需要連續的地址,你應該使用一個數組。 –
雖然這是錯誤的,但這是一個有趣的問題。除此之外,您可能預期內存位置是連續的 – Justin
您的地址相距32字節。如果它們是連續的,你會期望它們相距4個字節(假設'sizeof(int)== 4',它似乎通常是} – Justin