野指针:
指针变量中的值是非法的内存地址,进而形成野指针
野指针不是NULL指针,是指向不可用内存地址的指针
NULL指针并不危害,很好判断,也很好调试
指针所指向的变量在指针之前被销毁
使用已经释放过的指针
进行了错误的指针运算
进行了错误的强制类型转换
绝不返回局部变量和局部数组的地址
任何变量在定义后必须0初始化
字符数组必须确认0结束符后才能成为字符串
任何使用与内存操作相关的函数必须指定长度信息(确定长度信息相等)
指针变量中的值是非法的内存地址,进而形成野指针
野指针不是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;
}