程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 高質量C++/C編程指南(七)

高質量C++/C編程指南(七)

編輯:C++入門知識
第7章 內存治理
  歡迎進入內存這片雷區。偉大的Bill Gates 曾經失言:
  640K ought to be enough for everybody   — Bill Gates 1981 程序員們經常編寫內存治理程序,往往提心吊膽。假如不想觸雷,唯一的解決辦法就是發現所有潛伏的地雷並且排除它們,躲是躲不了的。本章的內容比一般教科書的要深入得多,讀者需細心閱讀,做到真正地通曉內存治理。   7.1內存分配方式
  內存分配方式有三種:   (1) 從靜態存儲區域分配。內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。例如全局變量,static變量。   (2) 在棧上創建。在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集中,效率很高,但是分配的內存容量有限。   (3) 從堆上分配,亦稱動態內存分配。程序在運行的時候用malloc或new申請任意多少的內存,程序員自己負責在何時用free或delete釋放內存。動態內存的生存期由我們決定,使用非常靈活,但問題也最多。   7.2常見的內存錯誤及其對策
  發生內存錯誤是件非常麻煩的事情。編譯器不能自動發現這些錯誤,通常是在程序運行時才能捕捉到。而這些錯誤大多沒有明顯的症狀,時隱時現,增加了改錯的難度。有時用戶怒氣沖沖地把你找來,程序卻沒有發生任何問題,你一走,錯誤又發作了。   常見的內存錯誤及其對策如下:   u 內存分配未成功,卻使用了它。   編程新手常犯這種錯誤,因為他們沒有意識到內存分配會不成功。常用解決辦法是,在使用內存之前檢查指針是否為NULL。假如指針p是函數的參數,那麼在函數的入口處用assert(p!=NULL)進行檢查。假如是用malloc或new來申請內存,應該用if(p==NULL) 或if(p!=NULL)進行防錯處理。
  u 內存分配雖然成功,但是尚未初始化就引用它。   犯這種錯誤主要有兩個起因:一是沒有初始化的觀念;二是誤以為內存的缺省初值全為零,導致引用初值錯誤(例如數組)。   內存的缺省初值究竟是什麼並沒有統一的標准,盡管有些時候為零值,我們寧可信其無不可信其有。所以無論用何種方式創建數組,都別忘了賦初值,即便是賦零值也不可省略,不要嫌麻煩。
  u 內存分配成功並且已經初始化,但操作越過了內存的邊界。   例如在使用數組時經常發生下標“多1”或者“少1”的操作。非凡是在for循環語句中,循環次數很輕易搞錯,導致數組操作越界。
  u 忘記了釋放內存,造成內存洩露。   含有這種錯誤的函數每被調用一次就丟失一塊內存。剛開始時系統的內存充足,你看不到錯誤。終有一次程序忽然死掉,系統出現提示:內存耗盡。   動態內存的申請與釋放必須配對,程序中malloc與free的使用次數一定要相同,否則肯定有錯誤(new/delete同理)。
  u 釋放了內存卻繼續使用它。   有三種情況:   (1)程序中的對象調用關系過於復雜,實在難以搞清楚某個對象究竟是否已經釋放了內存,此時應該重新設計數據結構,從根本上解決對象治理的混亂局面。   (2)函數的return語句寫錯了,注重不要返回指向“棧內存”的“指針”或者“引用”,因為該內存在函數體結束時被自動銷毀。   (3)使用free或delete釋放了內存後,沒有將指針設置為NULL。導致產生“野指針”。
  l 【規則7-2-1】用malloc或new申請內存之後,應該立即檢查指針值是否為NULL。防止使用指針值為NULL的內存。   l 【規則7-2-2】不要忘記為數組和動態內存賦初值。防止將未被初始化的內存作為右值使用。   l 【規則7-2-3】避免數組或指針的下標越界,非凡要當心發生“多1”或者“少1”操作。   l 【規則7-2-4】動態內存的申請與釋放必須配對,防止內存洩漏。   l 【規則7-2-5】用free或delete釋放了內存之後,立即將指針設置為NULL,防止產生“野指針”。   7.3指針與數組的對比
  C++/C程序中,指針和數組在不少地方可以相互替換著用,讓人產生一種錯覺,以為兩者是等價的。   數組要麼在靜態存儲區被創建(如全局數組),要麼在棧上被創建。數組名對應著(而不是指向)一塊內存,其地址與容量在生命期內保持不變,只有數組的內容可以改變。   指針可以隨時指向任意類型的內存塊,它的特征是“可變”,所以我們常用指針來操作動態內存。指針遠比數組靈活,但也更危險。   下面以字符串為例比較指針與數組的特性。   7.3.1 修改內容   示例7-3-1中,字符數組a的容量是6個字符,其內容為hello
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved