標籤: 暫無標籤

在標準C語言上,使用malloc等內存分配函數獲取內存即是從堆中分配內存,而在一個函數體中例如定義一個數組之類的操作是從棧中分配內存。從堆中分配的內存需要程序員手動釋放,如果不釋放,而系統內存管理器又不自動回收這些堆內存的話(實現這一項功能的系統很少),那就一直被佔用。如果一直申請堆內存,而不釋放,內存會越來越少,很明顯的結果是系統變慢或者申請不到新的堆內存。而過度的申請堆內存(可以試試在函數中申請一個1G的數組!),會導致堆被壓爆,結果是災難性的。


堆內存是區別於棧區、全局數據區和代碼區的另一個內存區域。堆允許程序在運行時動態地申請某個大小的內存

堆內存堆內存和棧內存
空間。

 

 

 

 




1 堆內存 -堆內存和棧內存

在學習C程序設計語言時,會遇到兩個很相似的術語:堆內存和棧內存。這兩個術語雖然只有一字之差,但是所表達的意義還是有差別的,堆內存和棧內存的區別可以用如下的比喻來看出:使用堆內存就象是自己動手做喜歡吃的菜肴,比較麻煩,但是比較符合自己的口味,而且自由度大。使用棧內存就象我們去飯館里吃飯,只管點菜(發出申請)、付錢和吃(使用),吃飽了就走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。操作系統中所說的堆內存和棧內存,在操作上有上述的特點,這裡的堆內存實際上指的就是(滿足堆內存性質的)優先隊列的一種數據結構,第1個元素有最高的優先權;棧內存實際上就是滿足先進後出的性質的數學或數據結構。

2 堆內存 -堆內存的分配

在標準C語言上,使用malloc等內存分配函數獲取內存即是從堆中分配內存,而在一個函數體中例如定義一個數組之類的操作是從棧中分配內存。從堆中分配的內存需要程序員手動釋放,如果不釋放,而系統內存管理器又不自動回收這些堆內存的話(實現這一項功能的系統很少),那就一直被佔用。如果一直申請堆內存,而不釋放,內存會越來越少,很明顯的結果是系統變慢或者申請不到新的堆內存。而過度的申請堆內存(可以試試在函數中申請一個1G的數組!),會導致堆被壓爆,結果是災難性的。

我們掌握堆內存的權柄就是返回的指針,一旦丟掉了指針,便無法在我們視野內釋放它。這便是內存泄露。而如果在函數中申請一個數組,在函數體外調用使用這塊堆內存,結果將無法預測。 我們知道在c/c 中定義的數組大小必需要事先定義好,他們通常是分配在靜態內存空間或者是在棧內存空間內的,但是在實際工作中,我們有時候卻需要動態的為數組分配大小,這時就要用到堆內存分配的概念。在堆內存分配時首先應該知道操作系統有一個記錄空閑內存地址的鏈表,當系統收到程序的申請時,會遍歷該鏈表,尋找第一個空間大於所申請空間的堆結點,然後將該結點從空閑結點鏈表中刪除,並將該結點的空間分配給程序,另外,對於大多數系統,會在這塊內存空間中的首地址處記錄本次分配的大小,這樣,代碼中的delete語句才能正確的釋放本內存空間。另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閑鏈表中。堆內存是向高地址擴展的數據結構,是不連續的內存區域。這是由於系統是用鏈表來存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆內存的大小受限於計算機系統中有效的虛擬內存。由此可見,堆內存獲得的空間比較靈活,也比較大。堆內存是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便.另外,在WINDOWS下,最好的方式是用VirtualAlloc分配內存,它直接在進程的地址空間中保留一快內存,雖然用起來最不方便。但是速度快,也最靈活。

3 堆內存 -堆內存分配時的重要函數

獲得堆內存:malloc()

堆內存動態分配堆內存
原型:externvoid*malloc(unsignedintnum_bytes);
功能:分配長度為num_bytes位元組的內存塊
說明:如果分配成功則返回指向被分配內存的指針,否則返回空指針NULL。當內存不再使用時,應使用free()函數將內存塊釋放。
malloc的語法是:指針名=(數據類型*)malloc(長度),(數據類型*)表示指針.
釋放堆內存:Delete()
原型:Delete(varS:String;Index,Count:Integer);
功能:Delete()刪除字元串S中從第Index個字元開始的Count個字元。若Index超出了S的長度,則不執行刪除的操作。若Index Count超出了S的長度,則刪除從Index到S末尾的字元。若Index或Count出現負數,則不執行刪除的操作。
舉例:
VarS:String='1234567890';執行Delete(S,1,3)后,S=『4567890』;執行Delete(S,9,8888)后,S='12345678'執行Delete(S,99,2)后,S=『1234567890』;執行Delete(S,-1,3)后,S=『1234567890』

4 堆內存 -典型示例

例1:
#include
#include

usingnamespacestd;
main()
{
intarraysize;//元素個數
int*array;//用於動態開闢數組的指針變數
cin>>arraysize;
array=(int*)malloc(arraysize*sizeof(int));//利用malloc在堆內存中開闢內存空間,它的大小是元素的個數乘以該數據類型的長度

for(inti=0;i
{
array[i]=i;
}

for(inti=0;i
{
cout<<<",";
}
cout<
free(array);//利用free釋放動態開闢的堆內存空間
cin.get();
cin.get();
}

這裡要特別注意個地方就是:array=(int*)malloc(arraysize*sizeof(int));malloc()的函數原形本身是void*malloc(size_tsize),由於動態分配的空間計算機並不知道是用來做什麼的所以是無類型的,但你要把它用在動態的整形數組上的時候就要顯式的轉換成int*了。

例2:
//malloc.c
#include
#include
main()
{
 char*p;
clrscr();//clearscreen
p=(char*)malloc(100);
if(p)
printf("MemoryAllocatedat:%x",p);
else
printf("NotEnoughMemory!\n");
free(p);
getchar();
return0;
}


5 堆內存 -相關詞條

隊列面向對象程序設計鏈表
循環隊列面向過程程序設計結構體


6 堆內存 -參考文獻

[1]、《C程序設計》譚浩強編著 高等教育出版社
[2]、《C++程序設計教程》錢能編著 清華大學出版社出版
[3]、《C++面向對象程序設計》Walter Savitch編著 清華大學出版社出版

  

上一篇[排它鎖]    下一篇 [ECOTEC]

相關評論

同義詞:暫無同義詞