1、記憶體分配錯誤
動態記憶體分配錯誤有兩種基本型別:記憶體錯誤和記憶體洩漏。
(1)記憶體錯誤
當乙個指標或者該指標所指向的記憶體單元成為無效單元,或者記憶體中分配的資料結構被破壞時,就會造成記憶體錯誤。指標未被初始化,指標被初始化為乙個無效位址,指標被不小心錯誤地修改,在與指標相關聯的記憶體區域被釋放後使用該指標(這種指標被稱為虛懸(dangling)指標),這些都會使指標變為無效指標。當通過乙個錯誤指標或者虛懸指針對記憶體進行寫入,或者將指標強制轉換為不匹配的資料結構,又或者是寫資料越界,記憶體自身也會遭到破壞。刪除未被初始化的指標、刪除非堆指標、多次刪除同一指標或者覆蓋乙個指標的內部資料結構,都會造成記憶體分配系統錯誤。
(2)記憶體洩漏
記憶體洩漏在被動態分配的記憶體沒有被釋放時產生。有許多情況會導致記憶體洩漏,如沒有在程式的全部執行路徑中釋放記憶體,沒有在析構函式中釋放所有的記憶體等。乙個程式在崩潰之前可執行的時間越長,則導致崩潰的原因與記憶體洩漏的關係越大。
windows會在程式結束的時候將****存收回,因此記憶體洩漏是個暫時性的問題。但為什麼必須消除記憶體洩露呢?首先,記憶體洩漏往往會導致系統資源的洩漏。動態分配記憶體往往不僅僅代表一塊儲存區域,還代表了某些型別的系統資源,如檔案、視窗、裝置上下文、gdi物件等。其次,高質量的程式和特定的伺服器程式必須能夠無限地執行下去。最後,記憶體洩漏往往是其他程式錯誤或不良程式設計習慣的徵兆。
導致內參洩漏的原因:忘記釋放記憶體;建構函式失敗;存在記憶體洩漏的析構函式;存在記憶體洩漏的異常處理程式;多個返回語句;使用錯誤形式的delete。
2、關於記憶體的初始化
在除錯版本裡,堆裡未被初始化的記憶體被0xcd位元組模式填充,堆裡釋放的記憶體被0xdd位元組模式填充。堆疊裡被初始化的記憶體被0xcc位元組模式填充。除錯版本和發布版本裡,未被初始化的全域性記憶體都被初始化為0。
3、記憶體虛擬位址空間
windows使用一組固定的範圍來分割程序的4gb虛擬位址空間,因此有時可通過檢視指標的返回值來判斷指標是否有效。
(1)windows2000虛擬位址空間劃分
0~0xffff(64kb):不能用來檢測空指標賦值(訪問衝突)
0x10000(64kb)~0x7ffeffff(2gb-64kb):win32程序私有的(非保留的),用於程式**和資料
0x7fff0000(2gb-64kb)~0x7fffffff(2gb):不能用來防止覆蓋os分割槽(訪問衝突)
0x800000000(2gb)~0xffffffff(4gb):為作業系統保留,不可訪問(訪問衝突)
(2)windows2000虛擬位址空間使用
0x00030000~0x0012ffff:執行緒棧
0x00130000~0x003fffff:堆(有時堆位於此處)
0x00400000~0x005fffff:可執行**
0x00600000~0x0fffffff:堆(有時堆位於此處)
0x77000000~0xffffffff:advapi32.dll、comctl32.dll、gdi32.dll、kernel32.dll、ntdll.dll、rpcrt4.dll、shell32.dll、user32.dll
其中,0x00400000是所有版本的windows能使用的最低基位址。
分配記憶體空間
void calloc size t nobj,size t size 分配足夠的記憶體給nobj個大小為size的物件組成的陣列,並返回指向所分配區域的第乙個位元組的指標 若記憶體不夠,則返回null.該空間的初始化大小為0位元組.char p char calloc 100,sizeof cha...
C C 分配記憶體空間
方法 c malloc calloc realloc free c new delete 函式原型 請求成功返回空間首位址,失敗返回 null include void malloc size t size 分配size位元組的連續記憶體,不負責初始化,使用memset初始化。void calloc...
Linux程式記憶體空間分配
先來看一段簡單 include include int main 執行結果 這時另開乙個終端,輸入cat proc 10073 maps,出現如下顯示 實際上,第一行是 區所佔的記憶體空間,804800 804900,實際上幾乎所有的linux程式 段都是從804800開始的,第二行是全域性棧區所佔...