野指標
- 指標變數中的值是非法的記憶體地址,進而形成野指標
- 野指標不是 NULL 指標,是指向不可用記憶體地址的指標
- NULL 指標並無危害,很好判斷,也很好除錯
- C 語言中無法判斷一個指標所儲存的地址是否合法
野指標的由來
- 區域性指標變數沒有被初始化
- 指標所指向的變數在指標之前被銷燬(返回區域性變數地址或陣列)
- 使用已經釋放過的指標
- 進行了錯誤的指標運算
- 進行了錯誤的強制型別轉換
例項分析: 野指標初探
#include <stdio.h>
#include <malloc.h>
int main()
{
int* p1 = (int*)malloc(40);
int* p2 = (int*)1234567; // 進行強制的錯誤型別轉換,造成野指標
int i = 0;
for(i=0; i<40; i++)
{
*(p1 + i) = 40 - i; // 記憶體越界訪問,造成野指標
}
free(p1);
for(i=0; i<40; i++)
{
p1[i] = p2[i]; // 使用已經釋放過的指標
}
return 0;
}
輸出:
段錯誤
基本原則
- 絕不返回區域性變數和區域性陣列的地址
- 任何變數在定義後必須 0 初始化
- 字元陣列必須確認 0 結束符後才能成為字串
- 任何使用與記憶體操作相關的函式必須指定長度資訊
例項分析: 無處不在的野指標
#include <stdio.h>
#include <string.h>
#include <malloc.h>
struct Student
{
char* name;
int number;
};
char* func()
{
char p[] = "D.T.Software";
return p; // 返回區域性陣列,warning
}
void del(char* p)
{
printf("%s
", p);
free(p);
}
int main()
{
struct Student s; // 指標成員沒有初始化,造成野指標
char* p = func(); // 返回區域性陣列,造成野指標
strcpy(s.name, p); // 使用野指標
s.number = 99;
p = (char*)malloc(5);
strcpy(p, "D.T.Software"); // 記憶體訪問越界
del(p);
return 0;
}
小結
記憶體錯誤是實際產品開發中最常見的問題,然而絕大多數的 bug 都可以通過遵循基本的程式設計原則和規範來避免
因此,在學習與使用的時候要牢記和理解記憶體操作的基本原則,目的和意義。
以上內容參考狄泰軟體學院系列課程,請大家保護原創!