在大型项目中我们对指针的应用是需要非常谨慎的,一不留神可能就会产生野指针或者造成内存泄漏。
以下情况是产生野指针的几种原因和实例。
一:指针为初始化直接使用
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[])
{
char *pArr;
*pArr = 'a';
printf("%c\n",*pArr);
return 0;
}
分析:因为指针未被初始化,所以指针所指向的也是随机的,他是个野指针,如果你引用指针,并修改这个指针所指向的内容,而如果这个指针所指向的内容恰好是另外一个程序的数据的话,你将其进行修改了,就会导致另外一个程序可能不能正常运行了。当然这种情况一般编译器会直接报错。
二:malloc或new之后的指针free或delete之后为置空
这是一种比较隐蔽的情况,编译之后可能也会有部分编译器不报错,如下程序
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[])
{
char *p = (char *)malloc(10);
*p = 'a';
*(p+1)='b';
free(p);
printf("%s\n",p);
return 0;
}
可以看到输出结果仍热是:ab
我们正常的情况期望是输出null。是因为当我释放了这块内存是,但是我还保留着这块内存的地址位置。仍然可以对这块地址进行访问赋值,是非常危险的。正确的做法如下程序。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[])
{
char *p = (char *)malloc(10);
*p = 'a';
*(p+1)='b';
free(p);
p=NULL;
printf("%s\n",p);
return 0;
}
三:指针的使用超过了变量的作用范围
当我们的指针指向一块已经被释放了的栈空间地址时(这块空间随时可能被系统分配给的其他的地方)但是我这里仍然对这个地址空间进行赋值,那么其行为是极其隐蔽和危险的。如下程序
#include <stdio.h>
#include <stdlib.h>
void test()
{
int *p;
{
int a = 10;
p = &a;
}
*p = 20;
printf("%d\n",*p);
}
int main(int argc, const char * argv[])
{
test();
return 0;
}
可以看到结果20。我们对一块以及不属于此进程存空间的内存地址进行赋值。
参看博客:野指针的第三种情况关于类的实例