- 青島雅思—專家談雅思考試發(fā)展趨勢(shì)
- 河南2011上半年自考網(wǎng)上報(bào)名入口 點(diǎn)擊進(jìn)入
- 2011年廣東省護(hù)士資格考試報(bào)名現(xiàn)場(chǎng)確認(rèn)時(shí)間
- 2011上半年樂山五通橋區(qū)會(huì)計(jì)從業(yè)考試報(bào)名3月10日-4月1
- 哈爾濱香坊區(qū)2011護(hù)士資格考試報(bào)名現(xiàn)場(chǎng)確認(rèn)時(shí)間
- 2011什邡第一次會(huì)計(jì)從業(yè)資格考試報(bào)名3月1日-4月15日
- 2011什邡第二次會(huì)計(jì)從業(yè)資格考試報(bào)名7月1日-9月16日
- 2011年中山市護(hù)士資格考試報(bào)名工作的通知
- 長(zhǎng)安大學(xué)2011考研成績(jī)查詢?nèi)肟?點(diǎn)擊進(jìn)入
- 西華大學(xué)2011考研成績(jī)查詢?nèi)肟?點(diǎn)擊進(jìn)入
- 中國(guó)地質(zhì)大學(xué)(武漢)2011考研成績(jī)3月3日查詢
- 中南民族大學(xué)2011考研成績(jī)查詢3月4日開始
- 沈陽建筑大學(xué)2011考研成績(jī)查詢?nèi)肟?點(diǎn)擊進(jìn)入
- 沈陽工業(yè)大學(xué)2011考研成績(jī)查詢?nèi)肟?點(diǎn)擊進(jìn)入
【武漢華嵌】?jī)?nèi)存分配函數(shù)用法小結(jié)
來源:求學(xué)問校網(wǎng) 發(fā)表時(shí)間:2011-10-26 瀏覽 52 次
作者:武漢華嵌技術(shù)部
一、用戶空間內(nèi)存分配:malloc、calloc、realloc
1、malloc原型如下:
extern void *malloc(unsigned int num_bytes);
功能:
分配長(zhǎng)度為num_bytes字節(jié)塊。
工作機(jī)制:
malloc函數(shù)的實(shí)質(zhì)體現(xiàn)在,它有一個(gè)將可用的內(nèi)存塊連接為一個(gè)長(zhǎng)長(zhǎng)的列表的所謂空閑鏈表。調(diào)用malloc函數(shù)時(shí),它沿連接表尋找一個(gè)大到足以滿足用戶請(qǐng)求所需要的內(nèi)存塊。然后,將該內(nèi)存塊一分為二(一塊的大小與用戶請(qǐng)求的大小相等,另一塊的大小就是剩下的字節(jié))。接下來,將分配給用戶的那塊內(nèi)存?zhèn)鹘o用戶,并將剩下的那塊(如果有的話)返回到連接表上。
2、calloc原型如下:
void *calloc(unsigned n,unsigned size);
功能:
在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配n個(gè)長(zhǎng)度為size的連續(xù)空間。
3、realloc原型如下:
extern void *realloc(void *mem_address, unsigned int newsize);
功能:
先按照newsize指定的大小分配空間,將原有數(shù)據(jù)從頭到尾拷貝到新分配的內(nèi)存區(qū)域,而后釋放原來mem_address所指內(nèi)存區(qū)域,同時(shí)返回新分配的內(nèi)存區(qū)域的首地址。即重新分配存儲(chǔ)器塊的地址。
注意:malloc和calloc的區(qū)別:
calloc在動(dòng)態(tài)分配完內(nèi)存后,自動(dòng)初始化該內(nèi)存空間為零,而malloc不初始化,里邊數(shù)據(jù)是隨機(jī)的垃圾數(shù)據(jù)。
realloc注意事項(xiàng):
a、realloc失敗的時(shí)候,返回NULL。
b、realloc失敗的時(shí)候,原來的內(nèi)存不改變,不會(huì)釋放也不會(huì)移動(dòng)。
c、假如原來的內(nèi)存后面還有足夠多剩余內(nèi)存的話,realloc的內(nèi)存等于原來的內(nèi)存加上剩余內(nèi)存,realloc還是返回原來內(nèi)存的地址; 假如原來的內(nèi)存后面沒有足夠多剩余內(nèi)存的話,realloc將申請(qǐng)新的內(nèi)存,然后把原來的內(nèi)存數(shù)據(jù)拷貝到新內(nèi)存里,原來的內(nèi)存將被free掉,realloc返回新內(nèi)存的地址。
d、如果size為0,效果等同于free()。
e、傳遞給realloc的指針必須是先前通過malloc(), calloc(), 或realloc()分配的。
f、傳遞給realloc的指針可以為空,等同于malloc。
以上三者的事例代碼如下:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
int main()
{
//最好每次內(nèi)存申請(qǐng)都檢查申請(qǐng)是否成功
//下面這段僅僅作為演示的代碼沒有檢查
char *pt1;
char *pt2;
char *pt3;
pt1 = (char *)malloc(sizeof(char)ၲ);
printf("pt1 = %p\n", pt1);
//以下可能會(huì)輸出亂碼,說明malloc分配的空間沒有被初始化為0
printf("%s\n", pt1);
scanf("%s", pt1);
pt2 = (char *)calloc(10,sizeof(char));
printf("pt2 = %p\n", pt2);
//以下輸出為空,說明calloc分配的空間被初始化為0
printf("%s\n", pt2);
pt3 = (char *)realloc(pt1, sizeof(char)ၼ);
printf("pt3 = %p\n", pt3);
//以下輸出pt1中原先的內(nèi)容。
printf("%s\n", pt3);
//以下是釋放申請(qǐng)的內(nèi)存空間
free(pt2);
free(pt3);
return 0;
}
二、內(nèi)核空間內(nèi)存分配:kmalloc、vmalloc
對(duì)于提供了MMU(存儲(chǔ)管理器,輔助操作系統(tǒng)進(jìn)行內(nèi)存管理,提供虛實(shí)地址轉(zhuǎn)換等硬件支持)的處理器而言,Linux提供了復(fù)雜的存儲(chǔ)管理系統(tǒng),使得進(jìn)程所能訪問的內(nèi)存達(dá)到4GB。
進(jìn)程的4GB內(nèi)存空間被人為的分為兩個(gè)部分--用戶空間與內(nèi)核空間。用戶空間地址分布從0到3GB(PAGE_OFFSET,在0x86中它等于0xC0000000),3GB到4GB為內(nèi)核空間。
從前面的介紹已經(jīng)看出,這兩個(gè)函數(shù)所分配的內(nèi)存都處于內(nèi)核空間,即從3GB~4GB;但位置不同,kmalloc()分配的內(nèi)存處于3GB~high_memory之間,這一段內(nèi)核空間與物理內(nèi)存的映射一一對(duì)應(yīng),而vmalloc()分配的內(nèi)存在vmalloc_start~4GB之間,這一段連續(xù)內(nèi)存區(qū)映射到物理內(nèi)存也可能是非連續(xù)的。
vmalloc()工作方式與kmalloc()類似,其主要差別在于前者分配的物理地址無需連續(xù),而后者確保頁在物理上是連續(xù)的(虛地址自然也是連續(xù)的)。
盡管僅僅在某些情況下才需要物理上連續(xù)的內(nèi)存塊,但是,很多內(nèi)核代碼都調(diào)用kmalloc(),而不是用vmalloc()獲得內(nèi)存。這主要是出于性能的考慮。vmalloc()函數(shù)為了把物理上不連續(xù)的頁面轉(zhuǎn)換為虛擬地址空間上連續(xù)的頁,必須專門建立頁表項(xiàng)。還有,通過vmalloc()獲得的頁必須一個(gè)一個(gè)的進(jìn)行映射(因?yàn)樗鼈兾锢砩喜皇沁B續(xù)的),這就會(huì)導(dǎo)致比直接內(nèi)存映射大得多的緩沖區(qū)刷新。因?yàn)檫@些原因,vmalloc()僅在絕對(duì)必要時(shí)才會(huì)使用——典型的就是為了獲得大塊內(nèi)存時(shí),例如,當(dāng)模塊被動(dòng)態(tài)插入到內(nèi)核中時(shí),就把模塊裝載到由vmalloc()分配的內(nèi)存上。
kamlloc函數(shù)原型:
#include<linux/slab.h>
void *kmalloc(size_t size, int flags);
(1)第一個(gè)參數(shù)是要分配的塊的大小
(2)第二個(gè)參數(shù)是分配標(biāo)志(flags),他提供了多種kmalloc的行為。
vamlloc函數(shù)原型:
#include <linux/vmalloc.h>
void *vmalloc(unsigned long size);
(1)第一個(gè)參數(shù)是要分配的塊的大小
我們用下面的程序來演示kmalloc和vmalloc的區(qū)別:
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
MODULE_LICENSE("GPL");
unsigned char *kmallocmem;
unsigned char *vmallocmem;
int __init mem_module_init(void)
{
//最好每次內(nèi)存申請(qǐng)都檢查申請(qǐng)是否成功
//下面這段僅僅作為演示的代碼沒有檢查
kmallocmem = (unsigned char*)kmalloc(100, 0);
printk("<1>kmallocmem addr=%x", kmallocmem);
vmallocmem = (unsigned char*)vmalloc(1000000);
printk("<1>vmallocmem addr=%x", vmallocmem);
return 0;
}
void __exit mem_module_exit(void)
{
kfree(kmallocmem);
vfree(vmallocmem);
}
module_init(mem_module_init);
module_exit(mem_module_exit);
總結(jié):
a、kmalloc和vmalloc分配的是內(nèi)核的內(nèi)存,malloc分配的是用戶的內(nèi)存。
b、kmalloc保證分配的內(nèi)存在物理上是連續(xù)的, kmalloc()分配的內(nèi)存在0xBFFFFFFF-0xFFFFFFFF以上的內(nèi)存中,driver一般是用它來完成對(duì)DS的分配,更適合于類似設(shè)備驅(qū)動(dòng)的程序來使用。
c、vmalloc保證的是在虛擬地址空間上的連續(xù),vmalloc()則是位于物理地址非連續(xù),虛地址連續(xù)區(qū),起始位置由VMALLOL_START來決定,一般作為交換區(qū)、模塊的分配。
d、kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相對(duì)較大(因?yàn)関malloc還可以處理交換空間)。
e、內(nèi)存只有在要被DMA訪問的時(shí)候才需要物理上連續(xù),vmalloc比kmalloc要慢。
f、vmalloc使用的正確場(chǎng)合是分配一大塊,連續(xù)的,只在軟件中存在的,用于緩沖的內(nèi)存區(qū)域。不能在微處理器之外使用。
g、vmalloc 中調(diào)用了kmalloc (GFP—KERNEL),因此也不能應(yīng)用于原子上下文。
hkmalloc和kfree管理內(nèi)核段內(nèi)分配的內(nèi)存,這是真實(shí)地址已知的實(shí)際物理內(nèi)存塊。
i、vmalloc對(duì)應(yīng)于vfree,分配連續(xù)的虛擬內(nèi)存,但是物理上不一定連續(xù)。
j、kmalloc分配內(nèi)存是基于slab,因此slab的一些特性包括著色,對(duì)齊等都具備,性能較好。物理地址和邏輯地址都是連續(xù)的。
一、用戶空間內(nèi)存分配:malloc、calloc、realloc
1、malloc原型如下:
extern void *malloc(unsigned int num_bytes);
功能:
分配長(zhǎng)度為num_bytes字節(jié)塊。
工作機(jī)制:
malloc函數(shù)的實(shí)質(zhì)體現(xiàn)在,它有一個(gè)將可用的內(nèi)存塊連接為一個(gè)長(zhǎng)長(zhǎng)的列表的所謂空閑鏈表。調(diào)用malloc函數(shù)時(shí),它沿連接表尋找一個(gè)大到足以滿足用戶請(qǐng)求所需要的內(nèi)存塊。然后,將該內(nèi)存塊一分為二(一塊的大小與用戶請(qǐng)求的大小相等,另一塊的大小就是剩下的字節(jié))。接下來,將分配給用戶的那塊內(nèi)存?zhèn)鹘o用戶,并將剩下的那塊(如果有的話)返回到連接表上。
2、calloc原型如下:
void *calloc(unsigned n,unsigned size);
功能:
在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配n個(gè)長(zhǎng)度為size的連續(xù)空間。
3、realloc原型如下:
extern void *realloc(void *mem_address, unsigned int newsize);
功能:
先按照newsize指定的大小分配空間,將原有數(shù)據(jù)從頭到尾拷貝到新分配的內(nèi)存區(qū)域,而后釋放原來mem_address所指內(nèi)存區(qū)域,同時(shí)返回新分配的內(nèi)存區(qū)域的首地址。即重新分配存儲(chǔ)器塊的地址。
注意:malloc和calloc的區(qū)別:
calloc在動(dòng)態(tài)分配完內(nèi)存后,自動(dòng)初始化該內(nèi)存空間為零,而malloc不初始化,里邊數(shù)據(jù)是隨機(jī)的垃圾數(shù)據(jù)。
realloc注意事項(xiàng):
a、realloc失敗的時(shí)候,返回NULL。
b、realloc失敗的時(shí)候,原來的內(nèi)存不改變,不會(huì)釋放也不會(huì)移動(dòng)。
c、假如原來的內(nèi)存后面還有足夠多剩余內(nèi)存的話,realloc的內(nèi)存等于原來的內(nèi)存加上剩余內(nèi)存,realloc還是返回原來內(nèi)存的地址; 假如原來的內(nèi)存后面沒有足夠多剩余內(nèi)存的話,realloc將申請(qǐng)新的內(nèi)存,然后把原來的內(nèi)存數(shù)據(jù)拷貝到新內(nèi)存里,原來的內(nèi)存將被free掉,realloc返回新內(nèi)存的地址。
d、如果size為0,效果等同于free()。
e、傳遞給realloc的指針必須是先前通過malloc(), calloc(), 或realloc()分配的。
f、傳遞給realloc的指針可以為空,等同于malloc。
以上三者的事例代碼如下:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
int main()
{
//最好每次內(nèi)存申請(qǐng)都檢查申請(qǐng)是否成功
//下面這段僅僅作為演示的代碼沒有檢查
char *pt1;
char *pt2;
char *pt3;
pt1 = (char *)malloc(sizeof(char)ၲ);
printf("pt1 = %p\n", pt1);
//以下可能會(huì)輸出亂碼,說明malloc分配的空間沒有被初始化為0
printf("%s\n", pt1);
scanf("%s", pt1);
pt2 = (char *)calloc(10,sizeof(char));
printf("pt2 = %p\n", pt2);
//以下輸出為空,說明calloc分配的空間被初始化為0
printf("%s\n", pt2);
pt3 = (char *)realloc(pt1, sizeof(char)ၼ);
printf("pt3 = %p\n", pt3);
//以下輸出pt1中原先的內(nèi)容。
printf("%s\n", pt3);
//以下是釋放申請(qǐng)的內(nèi)存空間
free(pt2);
free(pt3);
return 0;
}
二、內(nèi)核空間內(nèi)存分配:kmalloc、vmalloc
對(duì)于提供了MMU(存儲(chǔ)管理器,輔助操作系統(tǒng)進(jìn)行內(nèi)存管理,提供虛實(shí)地址轉(zhuǎn)換等硬件支持)的處理器而言,Linux提供了復(fù)雜的存儲(chǔ)管理系統(tǒng),使得進(jìn)程所能訪問的內(nèi)存達(dá)到4GB。
進(jìn)程的4GB內(nèi)存空間被人為的分為兩個(gè)部分--用戶空間與內(nèi)核空間。用戶空間地址分布從0到3GB(PAGE_OFFSET,在0x86中它等于0xC0000000),3GB到4GB為內(nèi)核空間。
從前面的介紹已經(jīng)看出,這兩個(gè)函數(shù)所分配的內(nèi)存都處于內(nèi)核空間,即從3GB~4GB;但位置不同,kmalloc()分配的內(nèi)存處于3GB~high_memory之間,這一段內(nèi)核空間與物理內(nèi)存的映射一一對(duì)應(yīng),而vmalloc()分配的內(nèi)存在vmalloc_start~4GB之間,這一段連續(xù)內(nèi)存區(qū)映射到物理內(nèi)存也可能是非連續(xù)的。
vmalloc()工作方式與kmalloc()類似,其主要差別在于前者分配的物理地址無需連續(xù),而后者確保頁在物理上是連續(xù)的(虛地址自然也是連續(xù)的)。
盡管僅僅在某些情況下才需要物理上連續(xù)的內(nèi)存塊,但是,很多內(nèi)核代碼都調(diào)用kmalloc(),而不是用vmalloc()獲得內(nèi)存。這主要是出于性能的考慮。vmalloc()函數(shù)為了把物理上不連續(xù)的頁面轉(zhuǎn)換為虛擬地址空間上連續(xù)的頁,必須專門建立頁表項(xiàng)。還有,通過vmalloc()獲得的頁必須一個(gè)一個(gè)的進(jìn)行映射(因?yàn)樗鼈兾锢砩喜皇沁B續(xù)的),這就會(huì)導(dǎo)致比直接內(nèi)存映射大得多的緩沖區(qū)刷新。因?yàn)檫@些原因,vmalloc()僅在絕對(duì)必要時(shí)才會(huì)使用——典型的就是為了獲得大塊內(nèi)存時(shí),例如,當(dāng)模塊被動(dòng)態(tài)插入到內(nèi)核中時(shí),就把模塊裝載到由vmalloc()分配的內(nèi)存上。
kamlloc函數(shù)原型:
#include<linux/slab.h>
void *kmalloc(size_t size, int flags);
(1)第一個(gè)參數(shù)是要分配的塊的大小
(2)第二個(gè)參數(shù)是分配標(biāo)志(flags),他提供了多種kmalloc的行為。
vamlloc函數(shù)原型:
#include <linux/vmalloc.h>
void *vmalloc(unsigned long size);
(1)第一個(gè)參數(shù)是要分配的塊的大小
我們用下面的程序來演示kmalloc和vmalloc的區(qū)別:
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
MODULE_LICENSE("GPL");
unsigned char *kmallocmem;
unsigned char *vmallocmem;
int __init mem_module_init(void)
{
//最好每次內(nèi)存申請(qǐng)都檢查申請(qǐng)是否成功
//下面這段僅僅作為演示的代碼沒有檢查
kmallocmem = (unsigned char*)kmalloc(100, 0);
printk("<1>kmallocmem addr=%x", kmallocmem);
vmallocmem = (unsigned char*)vmalloc(1000000);
printk("<1>vmallocmem addr=%x", vmallocmem);
return 0;
}
void __exit mem_module_exit(void)
{
kfree(kmallocmem);
vfree(vmallocmem);
}
module_init(mem_module_init);
module_exit(mem_module_exit);
總結(jié):
a、kmalloc和vmalloc分配的是內(nèi)核的內(nèi)存,malloc分配的是用戶的內(nèi)存。
b、kmalloc保證分配的內(nèi)存在物理上是連續(xù)的, kmalloc()分配的內(nèi)存在0xBFFFFFFF-0xFFFFFFFF以上的內(nèi)存中,driver一般是用它來完成對(duì)DS的分配,更適合于類似設(shè)備驅(qū)動(dòng)的程序來使用。
c、vmalloc保證的是在虛擬地址空間上的連續(xù),vmalloc()則是位于物理地址非連續(xù),虛地址連續(xù)區(qū),起始位置由VMALLOL_START來決定,一般作為交換區(qū)、模塊的分配。
d、kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相對(duì)較大(因?yàn)関malloc還可以處理交換空間)。
e、內(nèi)存只有在要被DMA訪問的時(shí)候才需要物理上連續(xù),vmalloc比kmalloc要慢。
f、vmalloc使用的正確場(chǎng)合是分配一大塊,連續(xù)的,只在軟件中存在的,用于緩沖的內(nèi)存區(qū)域。不能在微處理器之外使用。
g、vmalloc 中調(diào)用了kmalloc (GFP—KERNEL),因此也不能應(yīng)用于原子上下文。
hkmalloc和kfree管理內(nèi)核段內(nèi)分配的內(nèi)存,這是真實(shí)地址已知的實(shí)際物理內(nèi)存塊。
i、vmalloc對(duì)應(yīng)于vfree,分配連續(xù)的虛擬內(nèi)存,但是物理上不一定連續(xù)。
j、kmalloc分配內(nèi)存是基于slab,因此slab的一些特性包括著色,對(duì)齊等都具備,性能較好。物理地址和邏輯地址都是連續(xù)的。
武漢電腦培訓(xùn)培訓(xùn)相關(guān)新聞
武漢電腦培訓(xùn)相關(guān)課程
- 襄陽室內(nèi)設(shè)計(jì)培訓(xùn)學(xué)校
- 襄陽廣告設(shè)計(jì)培訓(xùn)學(xué)校
- 襄陽辦公文秘培訓(xùn)襄陽辦公應(yīng)用培訓(xùn)
- 襄陽園林景觀設(shè)計(jì)培訓(xùn)學(xué)校
- 襄陽建筑cad培訓(xùn)襄陽室內(nèi)cad培訓(xùn)襄陽家俱cad培訓(xùn)
- 襄陽建筑cad培訓(xùn)室內(nèi)cad培訓(xùn)
- 襄陽機(jī)械cad培訓(xùn)
- 襄陽2020年全國(guó)計(jì)算機(jī)等級(jí)考試報(bào)名和培訓(xùn)
- 襄陽建筑設(shè)計(jì)培訓(xùn)學(xué)校
- 襄陽3dmax培訓(xùn)襄陽cad培訓(xùn)襄陽vray培訓(xùn)襄陽ps培訓(xùn)
- 襄陽網(wǎng)頁設(shè)計(jì)培訓(xùn)襄陽網(wǎng)站制作培訓(xùn)
- 襄陽影視廣告動(dòng)漫設(shè)計(jì)培訓(xùn)
- 襄陽大眾室內(nèi)設(shè)計(jì)培訓(xùn)高級(jí)學(xué)校
- 襄陽家具Cad培訓(xùn)襄陽室內(nèi)Cad培訓(xùn)
武漢電腦培訓(xùn)相關(guān)機(jī)構(gòu)
武漢最新資訊
- 青島雅思—專家談雅思考試發(fā)展趨勢(shì)
- 河南2011上半年自考網(wǎng)上報(bào)名入口 點(diǎn)…
- 2011年廣東省護(hù)士資格考試報(bào)名現(xiàn)場(chǎng)確…
- 2011上半年樂山五通橋區(qū)會(huì)計(jì)從業(yè)考試…
- 哈爾濱香坊區(qū)2011護(hù)士資格考試報(bào)名現(xiàn)…
- 2011什邡第一次會(huì)計(jì)從業(yè)資格考試報(bào)名…
- 2011什邡第二次會(huì)計(jì)從業(yè)資格考試報(bào)名…
- 2011年中山市護(hù)士資格考試報(bào)名工作的…
- 長(zhǎng)安大學(xué)2011考研成績(jī)查詢?nèi)肟?點(diǎn)擊…
- 西華大學(xué)2011考研成績(jī)查詢?nèi)肟?點(diǎn)擊…
武漢推薦課程導(dǎo)航
雅思 | 口語 | 日語 | 韓語 | 德語 | 四六級(jí) | 商務(wù)英語 | 平面設(shè)計(jì) | 游戲動(dòng)漫 | 影視制作 | 室內(nèi)外設(shè)計(jì) | 動(dòng)畫設(shè)計(jì) | 網(wǎng)頁設(shè)計(jì) | 等級(jí)考試軟件工程 | 美容培訓(xùn) | 手機(jī)維修 | 廚師面點(diǎn) | 會(huì)計(jì)職稱 | 心理咨詢 | 人力資源