堆內存
堆內存
堆內存是區別於棧區、全局數據區和代碼區的另一個內存區域。堆允許程序在運行時動態地申請某個大小的內存空間。
堆內存和棧內存
動態分配堆內存
我們掌握堆內存的權柄就是返回的指針,一旦丟掉了指針,便無法在我們視野內釋放它。這便是內存泄露。而如果在函數中申請一個數組,在函數體外調用使用這塊堆內存,結果將無法預測。我們知道在c/c++ 中定義的數組大小必需要事先定義好,他們通常是分配在靜態內存空間或者是在棧內存空間內的,但是在實際工作中,我們有時候卻需要動態的為數組分配大小,這時就要用到堆內存分配的概念。在堆內存分配時首先應該知道操作系統有一個記錄空閑內存地址的鏈表,當系統收到程序的申請時,會遍歷該鏈表,尋找第一個空間大於所申請空間的堆結點,然後將該結點從空閑結點鏈表中刪除,並將該結點的空間分配給程序,另外,對於大多數系統,會在這塊內存空間中的首地址處記錄本次分配的大小,這樣,代碼中的delete語句才能正確的釋放本內存空間。另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閑鏈表中。堆內存是向高地址擴展的數據結構,是不連續的內存區域。這是由於系統是用鏈表來存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆內存的大小受限於計算機系統中有效的虛擬內存。由此可見,堆內存獲得的空間比較靈活,也比較大。堆內存是由new分配的內存,一般速度比較慢,而且容易產生內存碎片,不過用起來最方便。另外,在WINDOWS下,最好的方式是用VirtualAlloc分配內存,它直接在進程的地址空間中保留一快內存,雖然用起來最不方便。但是速度快,也最靈活。
獲得堆內存:malloc()
動態分配堆內存
原型:externvoid*malloc(unsignedintnum_bytes);
功能:分配長度為num_bytes位元組的內存塊
說明:如果分配成功則返回指向被分配內存的指針,否則返回空指針NULL。當內存不再使用時,應使用free()函數將內存塊釋放。
malloc的語法是:指針名=(數據類型*)malloc(長度),(數據類型*)表示指針.
例:int*p;
p=(int*)malloc(sizeof(int));
使用malloc函數分配內存時,返回值要經過類型轉換才可賦予一個指針變數。該函數如分配內存成功,則返回其始地址,否則返回NULL。頭文件為#include。
例:int*p,*q;
p=new int;//申請分配一個int型內存空間
p=new int(10);//申請一個int型空間存放10
q=new int[10];//申請分配10個int型的內存空間
new分配內存時不需要類型轉換。用new申請的空間必須要用delete釋放。而且指針值不能改變。形式有:delete指針變數名(可釋放一個內存單元)、delete[]指針變數名(可釋放若干個內存單元)。
例1:
#include
using namespace std;
main()
{
int array_size;//元素個數
int *array;//用於動態開闢數組的指針變數
cin>>array_size;
array=(int*)malloc(array_size*sizeof(int));
for(int i=0;i
array[i]=i;//輸入數組
for( i=0;i
cout<
cout<
free(array);//利用free釋放動態開闢的堆內存空間
cin.get();//按任意鍵結束
return 1;//返回值
}//////////////VC6.0通過 網頁格式符 請不要直接複製粘貼本段編譯
這裡要特別注意個地方就是:array=(int*)malloc(array_size*sizeof(int));malloc()的函數原形本身是void*malloc(size_tsize),由於動態分配的空間計算機並不知道是用來做什麼的所以是無類型的,但你要把它用在動態的整形數組上的時候就要顯式的轉換成int*了。
例2:
//malloc.c
#include "iostream"
using namespace std;
main()
{
char *p;
p=(char*)malloc(100*sizeof(char));
if(p)
printf("Memory Allocated at:%x \n",p);
else
printf("Not Enough Memory Available! \n");
free(p);
getchar();//按任意鍵結束
return 0;
}
目錄