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

C/C++ 指針精髓深度解析:從概念到工程陷阱全景圖

     編輯:C++ 入門

指針四大核心屬性

  1. 指針類型:決定解引用訪問大小、指針算術步長(`int*` +1 跳 4 字節)。
  2. 指針指向類型:即指針指向的對象類型(`int*` 指向 `int`)。
  3. 指針佔用內存:32 位系統 4 字節,64 位 8 字節(`sizeof(void*)`)。
  4. 指針值:存儲的地址數值,或 NULL (0)。

野指針三大來源

  1. **未初始化**:局部指針變量默認隨機值(如 `0xCCCCCCCC`)。
  2. **釋放後未置空**:`free(p); p = NULL;` 缺失,導致 `p` 指向已釋放內存。
  3. **變量生命周期結束**:返回局部變量地址、指向已銷毀對象(如類內引用成員綁定臨時對象)。

動態內存管理:malloc/free vs new/delete

  • `malloc`/`free`:C 標準庫,僅分配/釋放原始內存,**不調用構造/析構函數**。
  • `new`/`delete`:C++ 運算符,分配內存**並調用構造函數**,釋放前**調用析構函數**。
  • **嚴禁混用**:`malloc` 分配必須 `free`,`new` 必須 `delete`。對象類型必須用 `new`/`delete`。
  • 分配失敗:`malloc` 返回 NULL,`new` 拋出 `bad_alloc` (或 `nothrow` 版返回 NULL)。

指針參數傳遞陷阱

函數參數為值傳遞。若要修改實參指針指向,需用:

  • 二級指針 `void f(T **p)`
  • 引用 `void f(T *&p)` (C++ 推薦)
  • 返回值 `T* f()`

經典錯誤代碼集錦


// 1. 返回局部數組指針
char* getStr() { char p[]="hello"; return p; } // 錯:棧內存失效

// 2. 參數傳指針無法修改實參
void GetMem(char *p) { p = new char[20]; }
char *str = NULL; GetMem(str); // str 仍為 NULL

// 3. 釋放後繼續使用
free(p); strcpy(p, "oops"); // 野指針

// 4. 刪除數組用 delete 而非 delete[]
int *arr = new int[10]; delete arr; // 未定義行為,應 delete[]

// 5. const 指針 vs 指針常量
const int *p1; // 指向常量的指針,不可 *p1=...
int *const p2 = &x; // 常量指針,不可 p2=...

工程最佳實踐

  1. **定義即初始化**:`int *p = nullptr;`
  2. **釋放即置空**:`delete p; p = nullptr;`
  3. **使用智能指針**:`std::unique_ptr`、`std::shared_ptr` 管理生命周期,避免手動 `delete`。
  4. **避免裸指針傳遞所有權**:接口設計用智能指針或引用/值語義。
  5. **開啟編譯器警告**:`-Wall -Wextra -Werror` 捕獲未初始化、返回局部地址等問題。

總結

指針是 C/C++ 靈活性與危險的共同來源。掌握「類型、指向、大小、值」四屬性,理解內存分配/釋放與構造/析構綁定,識別野指針三大來源,避開參數傳遞陷阱,並在現代 C++ 中優先使用智能指針,方能駕馭指針威力。

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