指針變量中的值是非法的內存地址,進而形成野指針
野指針不是NULL指針,是指向不可用內存地址的指針
NULL指針並不危害,很好判斷,也很好調試
C語言中無法判斷一個指針所保存的地址是否合法
一個指針指向malloc申請的內存地址,其實指針是有效的,但是調用free後,這個地址將返還給內存,這個地址將不可用指針將變成野指針。
野指針的由來:
局部指針變量沒有被初始化(指針變量定義的時候應該被初始化爲NULL)指針所指向的變量在指針之前被銷燬
使用已經釋放過的指針
進行了錯誤的指針運算
進行了錯誤的強制類型轉換
局部變量的地址和局部數組在函數調用之後就被摧毀,如果指針指向原來的變量或者數組,就會形成野指針
實例分析:
#include <stdio.h>
#include <malloc.h>
int main()
{
int* p1 = (int*)malloc(40);
int* p2 = (int*)1234567; //錯誤的強制類型轉換,但此時不會產生程序崩潰,取決的何時使用p2
int i = 0;
for(i=0; i<40; i++) //指針運算產生野指針,改寫了非法的內存地址
{
*(p1 + i) = 40 - i; //出現越界:錯誤的指針運算。操作了沒有申請的內存空間(非法的內存地址)
}
free(p1); //釋放空間 但不負責將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; //返回一個局部數組
}
void del(char* p)
{
printf("%s\n", p);
free(p);
}
int main()
{
struct Student s; //未初始化指針,產生野指針
char* p = func(); //野指針
strcpy(s.name, p); //name也是野指針:s內的指針未初始化則爲野指針。 使用了野指針
s.number = 99;
p = (char*)malloc(5);
strcpy(p, "D.T.Software"); //內存越界 :本質是對野指針進行了操作
del(p);
return 0;
}
可更改爲:
struct Student
{
char* name;
int number;
};
char p[] = "D.T.Software";
char sp[] = "willwilling";
void del(char* p)
{
printf("%s\n", p);
free(p);
}
int main()
{
struct Student s = {sp, 0};
char* pp = p;
printf("p = %p\n", p);
printf("pp = %p\n", pp);
printf("pp = %s\n", pp);
strcpy(s.name, pp);
//s.name = pp;
s.number = 99;
pp = (char*)malloc(20);
strcpy(pp, "D.T.Software");
del(pp);
return 0;
}