malloc分配的內(nèi)存地址為什么不連續(xù)?
我們?cè)趯?xiě)程序中經(jīng)常會(huì)用到malloc函數(shù)進(jìn)行動(dòng)態(tài)內(nèi)存分配,但是我們有沒(méi)有想過(guò),在C語(yǔ)言中,向操作系統(tǒng)請(qǐng)求malloc內(nèi)存空間的地址是連續(xù)的嗎?
測(cè)試
每次申請(qǐng)一塊內(nèi)存空間
#include "stdio.h"
#include "stdlib.h"
int main()
{
void *addr0 = malloc(0);
void *addr1 = malloc(1);
void *addr2 = malloc(2);
printf("%p\n",addr0 );
printf("%p\n", addr1);
printf("%p\n", addr2);
printf("%ld\n", addr1 - addr0);
printf("%ld\n", addr2 - addr1);
free(addr0);
free(addr1);
free(addr2);
return 0;
}
測(cè)試結(jié)果如下
感覺(jué)像是有個(gè)固定的間隔,這里測(cè)試結(jié)果間隔是0x20,但地址并不是連續(xù)地址,具體為什么后面我們會(huì)講到。
用數(shù)組一次malloc 分配多個(gè)虛擬地址
#include "stdio.h"
#include "stdlib.h"
int main()
{
int* p;
int i;
p = (int *)malloc(10*sizeof(int));
for (i = 0; i < 10; i++)
{
p[i] = i;
printf("%d----%p\n", p[i],&p[i]);
}
getchar();
return 0;
}
結(jié)果如下:
可以看出,用一次malloc申請(qǐng)多個(gè)(數(shù)組)地址的是連續(xù)地址 ,結(jié)果也應(yīng)證了。
多次malloc 申請(qǐng)空間是否連續(xù)的呢?
#include "stdio.h"
#include "stdlib.h"
int main()
{
int* p;
int i;
for (i = 0; i < 1000; i++)//10、100、1000測(cè)試
{
p = (int*)malloc(sizeof(int));
*p = i;
printf("%d-----%p----%p\n", *p, p, p-1);
}
getchar();
return 0;
}
循環(huán)10次結(jié)果如下
循環(huán)100次結(jié)果如下
循環(huán)1000次結(jié)果如下
測(cè)試結(jié)果
-
我們用一次malloc申請(qǐng)多個(gè)(數(shù)組)地址的是連續(xù)地址 。 -
多次malloc 申請(qǐng)地址,通過(guò)對(duì)每一次申請(qǐng)的內(nèi)存空間地址和上一塊地址 (p-1)
作比較發(fā)現(xiàn),地址并不是連續(xù)的。 -
系統(tǒng)在每次malloc時(shí),從相隔固定長(zhǎng)度起開(kāi)始分配。
為什么呢?
其實(shí)這就是內(nèi)存邊界對(duì)齊的問(wèn)題,使用malloc分配的內(nèi)存空間在虛擬地址空間上是連續(xù)的,但是轉(zhuǎn)換到物理內(nèi)存空間上有可能是不連續(xù)的,
對(duì)用戶而言,所有內(nèi)存都是虛擬的,程序并不是直接運(yùn)行在物理內(nèi)存上,而是運(yùn)行在虛擬內(nèi)存上,然后由虛擬內(nèi)存轉(zhuǎn)換到物理內(nèi)存。
虛擬內(nèi)存地址到物理內(nèi)存地址進(jìn)行轉(zhuǎn)換時(shí),因?yàn)橛锌赡芟噜彽膬蓚€(gè)字節(jié)是在不同的物理分頁(yè)上,所以不一定是連續(xù)的。
長(zhǎng)按前往圖中包含的公眾號(hào)關(guān)注
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問(wèn)題,請(qǐng)聯(lián)系我們,謝謝!