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