首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C/C++ 指標精髓(二):記憶體管理與野指標防禦

     編輯:關於C++

指標賦予程式任意記憶體讀寫能力,亦帶來記憶體洩漏、野指標、雙重釋放等嚴重風險。本文深入剖析三種記憶體分配方式、malloc/free 與 new/delete 正確用法、記憶體耗盡處理、野指標成因與防禦、指標參數傳遞陷阱,並總結五條鐵律。

1.3 記憶體管理

1.3.1 三種分配方式

方式時機生命週期範例
靜態儲存區編譯期程式全程全域變數、static 變數
堆疊函式進入函式返回自動釋放區域變數、函式參數
堆積執行期 malloc/new程式員手動 free/delete動態陣列、物件

1.3.2 malloc/free 要點

void *malloc(size_t size);      // 只管位元組數,回傳 void*
void free(void *memblock);      // 僅需指標,自動依原大小釋放

// 正確用法:型別轉換 + sizeof
int *ip = (int*)malloc(sizeof(int) * length);
// 錯誤:sizeof(ip) 只得指標大小,非陣列大小
  • free(NULL) 安全無副作用;free(同指標兩次) 導致崩潰。

1.3.3 new/delete 要點

// 非 POD 型別必須用 new/delete(自動呼叫建構/解構函式)
class Object {
public: Object() { cout << "Init"; } ~Object() { cout << "Destroy"; }
};

Object *p = new Object;   // 分配 + 建構
delete p;                 // 解構 + 釋放

// 陣列形式
Object *arr = new Object[10];
delete [] arr;            // 必須加 []

核心差異:malloc/free 是庫函式,不受編譯器控制,無法自動執行建構/解構;new/delete 是運算子,編譯器保證語意完整。

1.3.4 記憶體耗盡處理三策略

  1. 函式級返回:if (!p) return;
  2. 程式級終止:if (!p) { cerr << "OOM"; exit(1); }
  3. 自訂新處理常式:_set_new_handler(MyHandler)(VC++),統一攔截 new 失敗。

註:32/64 位元虛擬記憶體機制使實際耗盡極難發生,但錯誤處理仍不可省略。

1.3.5 野指標五大成因與防禦

成因範例防禦
未初始化int *p; *p = 1;宣告即初始化:int *p = nullptr; 或 new int
釋放未歸零free(p); *p = 1;free(p); p = nullptr;
超出作用域{ int a; p = &a; } *p = 1;勿回傳/儲存區域變數位址
指標運算越界p += 100;邊界檢查、使用容器
多執行緒競態一緒釋放、一緒使用智慧指標、鎖、無鎖結構

1.3.6 指標參數傳遞陷阱

錯誤:試圖在函式內為指標參數分配記憶體

void GetMemory(char *p, int n) { p = (char*)malloc(n); } // 只修改副本
char *str = nullptr; GetMemory(str, 100); // str 仍為 nullptr

正解一:指標的指標

void GetMemory(char **p, int n) { *p = (char*)malloc(n); }
GetMemory(&str, 100); // 正確

正解二:函式回傳值

char *GetMemory(int n) { return (char*)malloc(n); }
str = GetMemory(100); // 簡潔明確

禁忌:回傳區域陣列/物件位址

char *GetString() { char s[] = "hello"; return s; } // 編譯警告,執行期亂碼

五條記憶體管理鐵律

  1. 分配後必檢 NULL:防止解參考空指標。
  2. 陣列/動態記憶體必初始化:防止以未定義值作右值。
  3. 嚴防下標越界:特別警惕 off-by-one。
  4. 申請與釋放嚴格配對:new ↔ delete、new[] ↔ delete[]、malloc ↔ free。
  5. 釋放後即歸零:p = nullptr; 斬斷野指標來源。

系列導航:(一) 指標概念與四要素 | (二) 記憶體管理與野指標防禦 | (三) 指標運算 | (四) 進階應用與陷阱

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved