分享
 
 
 

野指针,以及c++中的野指针[基础讲座]

王朝c/c++·作者佚名  2007-01-23
窄屏简体版  字體: |||超大  

这是我在学校论坛上发表的一篇帖子,针对初学者的基础讲解。

什么是野指针?

一个母亲有两个小孩(两个指针),一个在厨房,一个在卧室,(属于不同的代码块,其生存期不同)母亲让在厨房的小孩带一块蛋糕(指针指向的对象)给在卧室的小孩,这样在卧室的孩子才肯写作业。但这个在厨房的小孩比较淘气,他在走出厨房时自己将蛋糕吃了,没能带出来。而在卧室的没有吃到蛋糕,所以不肯完成他的作业。结果母亲却不知道卧室的孩子没有吃到蛋糕,还以为作业完了。结果第二天她就被老师召唤到办公室了。。。。。。。。事情麻烦了。

这样,那个在卧室的孩子就是野指针了,因为他没有得到应得的蛋糕,不能完成母亲交给他的作业。

这就是c中所讲的野指针。上面的小剧本不过演示了一种最基本的野指针的形成过程。更容易出现的情形是coder在编码时,大意之下使用了已经free过的指针。

对于年轻点的经验欠缺的coder来说是比较容易犯的错误,经验老到的程序员或者慎重采取成对编程的形式避免这种失误,或者使用引用计数器防止形成野指针。

总之,在c中,野指针也许性子野,但是控制起来也是有章可循。然而事情在c++中出现了变化。

coder们面临更大的麻烦了。c++程序员无可避免的要写很多这样那样的类。谁让c++是面向对象的呢?

我们在写类的时候难免要在构造函数中用new给类的指针数据成员分配内存。这本来没什么,动态分配内存是一种很常见的基本操作,我们在学数据结构时经常这么做,不是么?

但是伙计,事情并非这么简单。类是一种高级的用户自定义数据类型,看起来和结构、枚举这样的用户自定义类型没啥太大差别。如果你这样认为。。。。那你会死的很惨。类太复杂了,普通情况下使用类的对象并没有太大的问题,但是,当你要复制一个对象时,问题就来了。

比如我们知道,你要用一个对象初始化另一个对象时,c++是按位进行拷贝的(在某些情况下会使用默认生成的拷贝构造函数,而不是按位拷贝),即在内存里创建了初始化源对象的一个完全相同的拷贝。这在多数情况下已经足够了。但是,当你的对象在创建时为每个指针成员分配内存,也就是说类中有成员指向堆中的一块内存。当你的对象创建好后,类也将对象的指针成员指向了一块内存。如果你用这个对象去初始化另一个对象时,被初始化的对象和初始化的对象完全一样。这意味着,他们指向同一块内存,而不是重新为被初始化的对象分配内存。

这样麻烦就大了。如果一个对象销毁了,那么分配的内存也就销毁了(别忘了,类是有析构函数的,它负责在对象销毁时,释放动态分配的内存。难道你说你不在类中写上析构部分?那么可怜的孩子,那你就走向了另一个深渊,当你的程序运行数小时之后,系统会告诉你,内存不够用了。。。想象一下把你的程序用在腾讯的服务器上。。。。。),另一个对象就残缺不全了,这就像一对连体婴儿,他们共用了一部分器官,心脏或者肝脏。要救活一个,就牺牲了另一个。一个得病了,另一个也要遭殃。

可以说,这就是c++中更加变态的野指针。

什么?你说我不用对象初始化对象?那么我们会不会将一个对象作为变元传递给函数呢?我们很多时候都这样做。有时我们不得不将对象按值传递给一个函数,但是你要知道,按值传递是什么意思?它的意思就是,把实参的一个拷贝交给函数使用。这和刚才的初始化没什么两样,多数情况是按位拷贝,函数体内的对象与外面的对象的指针将指向同一块内存,即便在函数中的对象没有对这块内存进行过操作,但是当函数结束时。。。。析构函数将会被调用。。。。。。。。

还有一种与之相反的情况。。。 当你想要把一个在函数内的对象值返回给外面的对象时,这时候,函数内的对象会被析构。。。。同样一块内存被释放了两次。其后果是不可预见的。

当你把一个对象的值赋给另一个对象时,如果你没有重载赋值运算符,那么也可能会导致按位拷贝(当调用编译器生成的构造函数时一样会出问题)。最终产生一个野指针(一个隐藏在类内的毒瘤),或者释放同一块内存多次。

看到了么?害怕了么?是不是感到C++到处都是陷阱呢?不但有陷阱,到处都是危险品。所有c中的疑难问题,到了c++就成了一般问题了。好了不废话了,我们继续讲讲解决之道。

对于最后的这种赋值的情况,我们只有通过重载赋值运算符才能解决,也就是避免按位拷贝。

至于前面的都属于初始化,概括下来就是三种情况:

1.当一个对象初始化另一个对象时,例如在声明中;

2.把所创建的对象拷贝(按值)传递给一个函数时;

3.生成临时对象时,最常见的就是函数的返回值。

解决初始化时的按位拷贝问题(嗯嗯,可以明确地说,如果这个类的基因中没有任何虚的东西(虚基类,虚函数),它就会按位,但是不按位也会出同样的问题,所以对我们来说没什么区别),我们通过创建拷贝构造函数来解决。

基本的拷贝构造函数形式为:

classname (const classname &o)

{

//body here

}

拷贝构造函数就是针对这个问题而设计的。

恩,大家都明白了吧?不要让你的对象都变成可怜的连体人啊~~~~

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有