生死疆界(下)--- 在new与delete之间

2016-01-29 12:21 6 1 收藏

生死疆界(下)--- 在new与delete之间,生死疆界(下)--- 在new与delete之间

【 tulaoshi.com - C语言心得技巧 】

生死疆界(下)--- 在new与delete之间
作者:土豆

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)

上回《生死疆界(上)》说到: 咱们对着微软在背后做的手脚深感困惑,于是备好车马粮草,一路追杀进去,最后走进了死胡同,剩下的最后希望就是在这里摸摸,那里敲敲,看有没有暗藏机关。

这正是:探源码身陷绝境,求解脱心系参数。


还记得我们在delete p;前设的断点吗?好,让我们重新开始调试,按F5,从控制台输入"abcd",然后到这条语句前停止了,查看变量p的值,是0x00342c40,那好,打开vc监视内存的窗口memory,我们查看这个地址的值:


此后的内存情况不再用图片显示。只用红色标志的内存表示发生了变化的内存

看到了吗?你的宝贝"abcd"乖乖地躺在内存中,其后跟了一个0x00,那表示'''',字符串结束标志。一切都很正常,到底哪里出错了?难道是delete p用错了,而应该用delete[] p?try it,你会发现依然有相同的错误。

从这段内存中仍然看不出问题,仿佛一切风平浪静,其实是我们来晚了,在delete p前,内存早已经发生了翻天覆地的变化。 再一次重新进入程序,这次我们从一开始就监视内存。

00342C40 EE FE EE FE EE FE EE 铪铪铪.
00342C47 FE EE FE EE FE EE FE .


这是char *p = new char,执行前的内存。下面是执行后的:

00342C40 CD FD FD FD FD F0 AD 妄.
00342C47 BA 0D F0 AD BA 0D F0 ..瓠...


看不出什么问题,再往下执行吧:(cin>>p, 这次我们输入ab)

00342C40 61 62 00 FD FD F0 AD ab.
00342C47 BA 0D F0 AD BA 0D F0 ..瓠...


ab正确地放进了内存中,而且你可以看到cin还体贴地在ab后为你放了一个''''

还是没有什么问题?再往下走就是cout<<p了,它不会改动内存,再往下就到了delete p,到那时一切都晚了。 没错,就是这一步,静静的内存中早已经翻江倒海。

还记得static int __cdecl CheckBytes(unsigned char * pb, unsigned char bCheck, size_t nSize)中的bCheck, nSize吗? 如果当初你也监视变量的话,会发现bCheck = 253, nSize = 4。这就是这个内存侦测机制的命门。小时候喜欢看武打片,有一部叫做〈鹰爪铁布衫〉的,当时令我如痴如醉啊,看过的人一定还记得最后杀那老头的时候是先在他天灵上一拍,接着再在裤裆上捏一把,呵呵,bCheck就是天灵,nSize就是裤裆。

把253转换为16进制,是什么,没错,是FD。呵呵,别忙往下看,想一想,你找到真相了吗? 再看一眼char *p = new char执行后的内存,你发现了什么?p指向0x00342c40那个字节的值为CD,这是属于你的内存,看看后边跟的是什么,不多不少,恰恰是4个FD,恰恰是nSize个bCheck!

这个侦测内存非法访问的机制现在已经被我们开膛破肚了。微软在你申请的空间后加上四个FD,如果你访问了你非法访问内存,那么这些内存的内容将被改变(有一个问题我没有解决,我不知道FD代表什么,望知道的兄弟教我),在delete时,将检查由new产生的''''结束符后是否有连续四个字节都是FD,如果有证明没有发生非法内存访问,如果没有,那就该让_RPT3老兄出马了。
对于

char *p = new char;cin>>p;cout<<p;delete p;
这段代码,如果只输入一个字符a,cin>>p执行后的内存为

00342C40 61 00 FD FD FD F0 AD a..
00342C47 BA 0D F0 AD BA 0D F0 ..瓠...


虽然你只用了你申请的内存,但是cin为了讨好你给你加那个'''',覆盖了一个FD,这样,delete时照样报错,如果你这样做
char *p = new char[2];
那么cin>>p后内存为

00342C40 61 00 FD FD FD FD AD a..
00342C47 BA 0D F0 AD BA 0D F0 ..瓠...


来源:https://www.tulaoshi.com/n/20160129/1485697.html

延伸阅读
标签: 孕前
情商胎教更能“制造”天才宝宝! 怀胎十月,孕妈咪同时担负着两个生命的新陈代谢和情绪起伏,实在不是件很轻松的事。而保持愉悦的心情则是对宝宝最好的胎教。所以说,胎教时情商重要于智商。 日本有一位母亲,培养出了4个天才儿女,她写了一本叫《胎儿都是天才》的书。书中,她并不主张努力去培养什么天才儿童,而是强调家长的爱心对胎儿...
标签: 孕前
想怀孕?不能这样喝…… 据报道,未育女性每天过多喝咖啡,有可能使日后受孕的机会降低。 医学专家指出,咖啡中含有丰富的咖啡因,女性过多摄入可致雌激素分泌减少,而体内雌激素水平下降,就有可能对卵巢的排卵功能构成不利影响,使得tulaoShi.com受孕机会降低。 美国的人群调查结果显示,平均每天喝...
    C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。  关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。 请看下面的程序。 代码如下: #include iostream; using names...
日本东京医科大学的研究人员研究发现,男性的血型会显著地影响到癌症的发病率以及术后复发的概率。研究人员对在2004年~2010年间患有前列腺癌的555名病人进行了追踪随访调查后发现,O型血的男性在外科手术后复发的可能性很低;相比之下,A型血的男性在手术后复发的可能性最高,为35%。 研究者认为,血型是由不同的抗原和抗体所决定的,...
标签: Web开发
1、XML 是什么? XML仅仅是一种数据存放格式,这种格式是一种文本(虽然XML规范中也提供了存放二进制数据的解决方案)。 事实上有很多文本格式都可以用来存放数据,例如大家所熟悉的.ini文件。很多朋友在初学C语言或者Basic语言的时候,有时可能需要将源数据或者最终结果存放在一个文本文件里面,存放的格式当然由编写程序的人自己定了,那么...

经验教程

485

收藏

63
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部