第七章 記憶體管理(常見記憶體錯誤,指標陣列的比較)

2021-05-23 14:55:22 字數 2391 閱讀 8735

7.2 常見的記憶體錯誤及其對策

問題1:記憶體分配未成功,卻使用了它

解決辦法:在使用記憶體之前檢查指標是否為null。如果指標p是函式的引數,那麼在函式的入口處用assert(p!=null)進行檢查。如果是用malloc或new來申請記憶體,應該用if(p==null)或if(p!=null)進行防錯處理。

問題2:記憶體分配雖然成功,但是尚未初始化就引用它。

問題3:記憶體分配成功並且已經初始化,但操作越過了記憶體的邊界

問題4:忘記了釋放記憶體,造成記憶體洩漏

問題5:釋放了記憶體卻繼續使用它

【規則7-2-1】用malloc 或new 申請記憶體之後,應該立即檢查指標值是否為null。防止使用指標值為null 的記憶體。

【規則7-2-2】不要忘記為陣列和動態記憶體賦初值。防止將未被初始化的記憶體作為右值使用。

【規則7-2-3】避免陣列或指標的下標越界,特別要當心發生「多1」或者「少1」操作。

【規則7-2-4】動態記憶體的申請與釋放必須配對,防止記憶體洩漏。

【規則7-2-5】用free 或delete 釋放了記憶體之後,立即將指標設定為null,防止產生「野指標」。

7.3 指標與陣列的對比

7.3.1 修改內容

示例7-3-1 中,字元陣列a 的容量是6 個字元,其內容為hello/0。a 的內容可以改變,如a[0]= 『x』。指標p 指向常量字串「world」(位於靜態儲存區,內容為world/0),常量字串的內容是不可以被修改的。從語法上看,編譯器並不覺得語句p[0]= 『x』有什麼不妥,但是該語句企圖修改常量字串的內容而導致執行錯誤。

char a = "hello";

a[0] = 'x';

cout << a << endl;

char *p = "world"; // 注意p 指向常量字串

p[0] = 'x'; // 編譯器不能發現該錯誤,執行時出錯

cout << p << endl;

cin.get();

7.3.2 內容複製與比較

不能對陣列名進行直接複製與比較。示例7-3-2 中,若想把陣列a 的內容複製給陣列b,不能用語句 b = a ,否則將產生編譯錯誤。應該用標準庫函式strcpy 進行複製。同理,比較b 和a 的內容是否相同,不能用if(b==a) 來判斷,應該用標準庫函式strcmp進行比較。

語句p = a 並不能把a 的內容複製指標p,而是把a 的位址賦給了p。要想複製a的內容,可以先用庫函式malloc 為p 申請一塊容量為strlen(a)+1 個字元的記憶體,再用strcpy 進行字串複製。同理,語句if(p==a) 比較的不是內容而是位址,應該用庫函式strcmp 來比較。

// 陣列…

char a = "hello";

char b[10];

strcpy(b, a); // 不能用b = a;

if(strcmp(b, a) == 0) // 不能用if (b == a)

// 指標…

int len = strlen(a);

char *p = (char *)malloc(sizeof(char)*(len+1));

strcpy(p,a); // 不要用p = a;

if(strcmp(p, a) == 0) // 不要用if (p == a)

示例-3-2 陣列和指標的內容複製與比較

7.3.3 計算記憶體容量

用運算子sizeof 可以計算出陣列的容量(位元組數)。示例7-3-3(a)中,sizeof(a)的值是12(注意別忘了』/0』)。指標p 指向a,但是sizeof(p)的值卻是4。這是因為sizeof(p)得到的是乙個指標變數的位元組數,相當於sizeof(char*),而不是p 所指的記憶體容量。c++/c 語言沒有辦法知道指標所指的記憶體容量,除非在申請記憶體時記住它。

注意當陣列作為函式的引數進行傳遞時,該陣列自動退化為同型別的指標。

示例7-3-3(b)中,不論陣列a 的容量是多少,sizeof(a)始終等於sizeof(char *)。

char a = "hello world";

char *p = a;

cout<< sizeof(a) << endl; // 12 位元組

cout<< sizeof(p) << endl; // 4 位元組

示例-3-3(a)計算陣列和指標的記憶體容量

void func(char a[100])

cout<< sizeof(a) << endl; // 4 位元組而不是位元組

示例-3-3(b)陣列退化為指標

第七章檔案管理

為了能對乙個檔案進行正確的訪問,必須為檔案設定用於描述和控制檔案的資料結構,稱之為 檔案控制塊 fcb 檔案與檔案控制塊一一對應。把檔案控制塊的有序集合稱為檔案目錄,即乙個檔案控制塊就是乙個目錄項。通常乙個檔案目錄也被看作是乙個檔案,稱為目錄檔案。檔案管理的操作 基本資訊記錄 fcb,目錄項 方便檢...

第七章 檔案管理

檔案管理 把所管理的程式和資料組織成一系列的檔案,並能進行合理的儲存 使用等操作。1.基本概念 資料項 描述物件某種屬性的字符集 是資料組織中可以命名的最小邏輯資料單位。記錄 一組相關資料項集合,描述物件某方面的屬性 關鍵字 乙個記錄中的乙個或幾個資料項的集合,用於唯一的標識乙個記錄。檔案 由建立者...

第七章 錯誤處理

不使用錯誤碼,使用異常。裡面有個例子,測試驅動開發的。先寫測試用例,異常測試的。然後寫出佔位 再跑測試用例,通不過,修改佔位 測試通 過,然後重構 重構後測試用例 正常跑過,那麼重構成功。自定義異常類 將第三方api進行打包處理。其實就是對第三方api進行封裝處理,這樣也減少了對它的依賴。別返回nu...