C语言产生野指针的原因

#include <iostream>
#include <string>

using namespace std;
void main(){
	int a = 10;
	int b = 20;
	int c=0;
	int *p = &a;
	cout << *p << endl;
	//1等号左边和右边
	// *p在等号左边表示给内存赋值
	*p = b;  
	cout << *p << endl;  //*p=20

	// *p在等号右边表示从内存中取值
	c = *p;
	cout << c<< endl;  //c=20


	//2野指针
	char *p1 = NULL;  //一开始指向null,内存空间地址是0
	p1 = (char*)malloc(100);  //改变了p1的指向
	strcpy(p1, "11111");
	cout << "p1=:"<<p1<<"   *p1=" <<*p1<< endl;
	if (p1!=NULL)
	{
		free(p1); //把指针变量指向的内存空间释放了 free和delete只是把指针所指的 内存给释放掉,但并没有把指针本身释放
		p1 = NULL;  //但指针变量还没复原,需要加上这句话。 用free或delete释放了内存之后,就应立即将指针设置为NULL,防止产生“野指针”
	}

	if (p1 != NULL)
	{
		free(p1);

	}


	system("pause");
}

产生野指针原因的本质:指针变量和它所指内存空间变量是两个不同的概念。

解决办法:三步曲

1、定义指针时,把指针变量赋值成NULL

2、释放内存时,先判断指针变量是否为NULL

3、释放完内存后,把指针变量重新复制成NULL

 

 

3)、野指针产生模型图

 

4)、野指针易错难点分析:指针做函数参数

void getMem3(intcount,char *p)

{

   char *tmp =NULL;

   tmp = (char *)malloc(100 *sizeof(char));//char tmp[100];

   p = tmp;

   //在这个场景下,你给形参赋值了,没有给实参赋值 ,因此分配空间的地址并没传给实参

}

void getMem4(intcount,char **p/*out*/)

{

   char *tmp =NULL;

   tmp = (char *)malloc(100 *sizeof(char));//char tmp[100];

   //间接的修改实参

   *p = tmp;

}

//函数调用的时候,这个场景修改不了实参

int FreeMem1(char *p)

{

   if (p == NULL)

   {

      return -1;

   }

   if (p != NULL)

   {

      free(p);

      p =NULL;//只是把形参重置为NULL,但是实参并没有改变

   }

   return 0;

}

int FreeMem2(char **p)    //实参地址传过来了

{

   if (*p == NULL)

   {

      printf("内存已经释放,不会产生野指针\n");

      return -1;

   }

   if (*p != NULL)

   {

      free(*p);

      *p =NULL;//把实参重置为NULL了,再也不会产生野指针了

   }

   return 0;

}

void main()

{

   char *myp =NULL;

   //getMem3(100, myp);

   getMem4(100, &myp);

   strcpy(myp, "hello 123456");

    //FreeMem1(myp);

   FreeMem2(&myp);

   system("pause");

}

产生问题的本质原因指针做函数参数中形参和实参是两个不同的概念

没有真正理解指针做函数参数中地址传递和值传递的区别,这是典型的易错模型.


。指针p被free以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,p成了“野指针”。如果此时不 把p设置为NULL,会让人误以为p是个合法的指针。


内存 被释放了,并不表示指针会消亡或者成了NULL指针。




展开阅读全文

没有更多推荐了,返回首页