很多新學(xué)C語言的童鞋在用到動態(tài)內(nèi)存分配的時(shí)候,對選擇哪種分配函數(shù)及其有何區(qū)別搞不清楚僧界,那么下文就認(rèn)真的講講它們的種種。
(1)C語言的內(nèi)存分配方式
-
從靜態(tài)存儲區(qū)域分配
這些在程序編譯的時(shí)候就已經(jīng)分配好梁剔,且在程序的整個(gè)運(yùn)行期間都固定不變豌鹤。
使用這種方式分配內(nèi)存空間的數(shù)據(jù)主要包括:
代碼段(DATA Section)的程序自身語句文本(包括嵌在代碼里的字符串常量)寂呛,已經(jīng)初始化的全局變量和靜態(tài)變量 其馏。
.BSS段的未初始化的全局變量骗奖。
- 在棧stack上分配
這種方式由系統(tǒng)自動分配剧蹂,函數(shù)退出時(shí)也由系統(tǒng)自動釋放声功。
使用這種方式分配內(nèi)存空間的數(shù)據(jù)主要包括:
本地變量和函數(shù)參數(shù)
- 從堆heap上分配,亦稱動態(tài)內(nèi)存分配
程序在運(yùn)行的時(shí)候用malloc類或new動態(tài)申請的內(nèi)存宠叼,由用戶自己負(fù)責(zé)用free或delete釋放先巴。動態(tài)內(nèi)存的生存期由用戶決定,使用非常靈活冒冬,但問題也最多伸蚯。
使用這種方式分配內(nèi)存空間的數(shù)據(jù)主要包括:
自定義輸入緩存或用于接收用戶輸入數(shù)據(jù)的變量(數(shù)組、結(jié)構(gòu)體等)
(2)跟內(nèi)存申請相關(guān)的函數(shù)
void* malloc(size_t size)
作用:從堆中分配size個(gè)字節(jié)的空間窄驹,成功則返回空間首地址朝卒,失敗則返回空指針。它的聲明位于stdlib.h頭文件中乐埠。
我們在編程中必須注意分配失敗的情況抗斤,以使程序更加健壯和完備。所以一般會對其進(jìn)行包裝:
void *
xmalloc (size_t size)
{
void *value = malloc (size);
if (value == 0)
fatal ("virtual memory exhausted");
return value;
}
同時(shí)丈咐,由于它并沒有對分配的空間進(jìn)行任何操作瑞眼,因此基本上malloc之后,需要調(diào)用函數(shù)memset來初始化。
struct foo *ptr;
...
ptr = (struct foo *) malloc (sizeof (struct foo));
if (ptr == 0)
abort ();
memset (ptr, 0, sizeof (struct foo));
void * calloc (size_t count, size_t eltsize)
作用:從堆中分配size個(gè)字節(jié)的已經(jīng)清零的空間棵逊,成功則返回空間首地址伤疙,失敗則返回空指針。它的聲明位于stdlib.h頭文件中辆影。
它的實(shí)現(xiàn)等同于:
void *
calloc (size_t count, size_t eltsize)
{
size_t size = count * eltsize;
void *value = malloc (size);
if (value != 0)
memset (value, 0, size);
return value;
}
void * realloc (void *ptr, size_t newsize)
作用:用來對之前申請的動態(tài)內(nèi)存重新進(jìn)行分配大小(擴(kuò)容或縮小)徒像。
參數(shù)解釋:ptr必須為之前通過malloc或calloc等函數(shù)申請的動態(tài)內(nèi)存首地址;newsize為你現(xiàn)在需要的大小蛙讥。
注意事項(xiàng):
1 如果是擴(kuò)容锯蛀,它不能保證后加的空間一定是接在原來申請的內(nèi)存空間之后的,因?yàn)橛锌赡芷渲蟮目臻g已經(jīng)被使用了次慢。此時(shí)系統(tǒng)會找一塊大小符合你要求的連續(xù)空間旁涤,并同時(shí)把原來空間內(nèi)容復(fù)制到新空間翔曲,最后再釋放原空間。
2 如果擴(kuò)容失敗劈愚,則原空間內(nèi)容不受影響瞳遍。
3 如果參數(shù)ptr為空,則其動作同malloc菌羽。
但是當(dāng)我們使用時(shí)掠械,為了程序的健壯性和完備性,在使用時(shí)我們需要包裝一下:
void *
xrealloc (void *ptr, size_t size)
{
void *value = realloc (ptr, size);
if (value == 0)
fatal ("Virtual memory exhausted");
else
return value;
void * reallocarray (void *ptr, size_t nmemb, size_t size)
該函數(shù)作用及各參數(shù)同realloc算凿,唯一的不同是當(dāng)發(fā)生乘法溢出時(shí)份蝴,會進(jìn)行錯(cuò)誤提示。
void * aligned_alloc (size_t alignment, size_t size)
作用:函數(shù)分配一個(gè)地址alignment對齊的大小為size的內(nèi)存空間氓轰。
參數(shù)解釋:alignment代表地址對齊參數(shù),必須為2的倍數(shù)浸卦,且size也必須是alignment的倍數(shù)署鸡。
如果分配成功則返回內(nèi)存首地址,否則返回空限嫌,同時(shí)依據(jù)錯(cuò)誤原因設(shè)置錯(cuò)誤代碼errno為ENOMEN或EINVAL