野指標不是空指標,而是指向已失效/未初始化/非法記憶體的指標。位址非 NULL,if(p) 判斷為真,但解參考導致未定義行為。本文以實測代碼驗證三大成因,揭示偵測盲區。
int* p; // 棧上垃圾值
*p = 10; // 寫入隨機位址 → 崩潰/靜默破壞
正確:int* p = NULL; 或 int* p = malloc(sizeof(int));
char* p = malloc(100);
strcpy(p, "Hello");
printf("位址: %p\n", p); // 0x00...
free(p);
printf("位址: %p\n", p); // 仍為 0x00... 但已失效
// if(p != NULL) strcpy(p, "World"); // 野指標攻擊
實測證明:free 釋放的是指向的記憶體,非指標變數本身。指標位址不變,內容成垃圾。
正確:free(p); p = NULL;
class A { public: void Func() { cout << "A::Func"; } };
void Test() {
A* p;
{ A a; p = &a; } // a 解構,記憶體回收
p->Func(); // 編譯器可能優化仍能跑,但屬 UB
}
正確:延長物件生命週期、動態配置 new A + 智慧指標管理。
if (p != NULL) 完全無效(位址非 0)T* p = nullptr;free(p); p = nullptr; / delete p; p = nullptr;shared_ptr、unique_ptr、或呼叫端提供儲存空間delete,避免重複釋放-Wall -Wextra -Wuninitialized-fsanitize=address)、Valgrind Memcheck
#include
void ModernTest() {
auto p = std::make_unique(); // 唯一所有權
p->Func();
// 離開作用域自動 delete,不可能野指標
}
結論:野指標源於手動記憶體管理的本質複雜性。C++ 專案應全面棄用裸指標擁有權,改用 RAII 容器與智慧指標,從語言層面根除此類 Bug。