这篇文章给大家分享的是有关如何解决c++野指针的问题的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。
指向非法的内存地址指针叫作野指针(野指针),也叫悬挂指针(悬空指针),意为无法正常使用的指针。
<强> 2.1使用未初始化的指针强>
出现野指针最典型的情形就是在定义指针变量之后没有对它进行初始化,如下面的程序。
# include & lt; iostream> 使用名称空间性病; int main () { int * p; cout<& lt; *术;& lt; endl;//编译通过,运行时出的错 }
<强> 2.2指针所指的对象已经消亡强>
指针指向某个对象之后,当这个对象的生命周期已经结束,对象已经消亡后,仍使用指针访问该对象,将出现运行时错误。考察如下程序。
# include & lt; iostream> 使用名称空间性病; int * retAddr () { int num=10; 返回,num; } int main () { int * p=零; p=retAddr (); cout<& lt;及术中;& lt; endl; cout<& lt; *术;& lt; endl; }
以上程序编译和运行都没有错误,输出结果如下:
001 afd48
引用>
1701495776最后一行,输出的并非想象中的num的值10,因为变量num是存储在栈空间的局部变量,离开函数超出其作用域后就会被释放掉,因此输出的值就是不确定的值了。
注意:
,(1)如果将<代码> cout<& lt;及术中;& lt;endl> 代码;注释掉,可以正常输出num的值为10,或者将<代码> cout<& lt; *术;& lt; endl> 代码;放在前面,也能正常输出,原因是局部变量num的内存空间虽然在函数retAddr()调用结束后被回收,但是其值还没有被修改,语句<代码> cout<& lt;及术中;& lt; endl> 代码;实际上是调用cout对象的成员函数<代码> ostream&operator<& lt;() 代码>,重新使用了retAddr()调用时使用的栈空间,此时num的内存空间被改写,输出了不确定值。(2)修改p指向的内存空间的值,可以正常编译运行。
int main () { int * p=零; p=retAddr (); * p=11; cout & lt; & lt;* p & lt; & lt;endl; }上面的代码输出11。这里p指向的地址空间虽然不属于主函数的栈空间,但是操作系统在程序运行时会预先开辟一段可用的栈空间,供用户程序使用。一般情况下,Windows默认为1 m, Linux默认为10米,预先开辟的栈空间并不是系统保护性地址,可以由程序任意改写并访问,所以可以更改p指向的内存空间的值并访问输出。
<强> 2.3指针释放后之后未置空强>
指针p被免费或者删除之后,没有置为空,让人误以为p是个合法的指针。对指针进行自由和删除,只是把指针所指的内存空间给释放掉,但并没有把指针本身置空,此时指针指向的就是“垃圾”内存。释放后的指针应立即将指针置为空,防止产生野指针。考察如下程序。
# include & lt; iostream> 使用名称空间性病; int main () { int * p=零; p=new int [10]; 删除p; cout<& lt;“p [0]:“& lt; & lt; p [0] & lt; & lt; endl; }程序输出结果是一个随机值,因为此时的指针所指向的空间是垃圾内存,存放着随机值。
野指针有时比较隐蔽,编译器不能发现,为了防止野指针带来的危害,开发人员应该注意以下几点。
, (1) c++引入了引用机制,如果使用引用可以达到编程目的,就可以不必使用指针。因为引用在定义的时候,必须初始化,所以可以避免野指针的出现。(2)如果一定要使用指针,那么需要在定义指针变量的同时对它进行初始化操作。定义时将其置位零或者指向一个有名变量。
(3)对指针进行免费或者删除操作后,将其设置为零。对于使用免费的情况,常常定义一个宏或者函数xfree来代替免费置空指针:
# define xfree (x)自由(x);x=零;感谢各位的阅读!关于如何解决c++野指针的问题就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到吧!
如何解决c++野指针的问题