c/c++運行期庫包含一個堆棧檢查函數,當編譯源代碼的時候,編譯器在恰當的時候(這個在下面講)生成對該函數的調用
下面我們看個函數
void SomeFunction()
{
int nValues[4000];
nValues[0]=0;
}
該函數需要16000個字節的堆棧空間,編譯器生成的用於分配該堆棧空間的代碼只是將堆棧指針遞減16000個字節,但是在程序試圖訪問該內存之前,系統並不會將物理存儲器分配給堆棧的較低區域
這裏需要說明下,堆棧指針的初始地址是最高的,線程運行過程中,由於不斷的分配內存,堆棧指針是下移的
這裏附上堆棧結構的講解篇
http://blog.csdn.net/baidu_25539425/article/details/78927326
由於物理存儲器不會被提交給較低區域,所以,我們需要在適當的時候運行堆棧檢查函數,那麼什麼時候是適當的呢
就是當我們需要的內存的數量大於CPU系統的頁面大小的時候,就需要進行堆棧檢查。當然這些全部是由系統完成的
以前我們講過,intel系的CPU的頁面大小爲4KB,Alpaha系的CPU的頁面大小爲8KB,所以在windows系統下,只要函數所需的內存的數量大於4096個字節,系統就會自動調用堆棧檢查函數
下面我們來展示一段堆棧檢查函數的僞代碼
#ifdef _M_ALPHA
#define PAGESIZE (8*1024)
#else
#define PAGESIZE (4*1024)
#endif
void StartCheck(int BytesNeedFromStack)
{
PBYTE pbStackPtr=(CPU's stack pointer);//獲取堆棧指針的地址
while(BytesNeedFromStack>=PAGESIZE)
{
pbStackPtr-=PAGESIZE;//堆棧指針下移
pbStackPtr[0]=0;//給指針所在的頁面分配物理存儲器
BytesNeedFromStack-=PAGESIZE;
}
}
大家可能對pbStackPtr[0]=0這句話不太理解,我前面說過
但是在程序試圖訪問該內存之前,系統並不會將物理存儲器分配給堆棧的較低區域
所以,這句話的意思是訪問該內存,實際上,訪問過後,系統就會把該頁面提交到物理存儲器