青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 14, comments - 4, trackbacks - 0, articles - 0

野指針

Posted on 2006-07-05 00:32 will 閱讀(1287) 評論(0)  編輯 收藏 引用 所屬分類: 技術(shù)探索
?????????野指針,也就是指向不可用內(nèi)存區(qū)域的指針。通常對這種指針進行操作的話,將會使程序發(fā)生不可預(yù)知的錯誤。但是,我在文中要說的,就是野指針的“安全”使用方法以及其內(nèi)部的原因.

首先請諸位看以下一段“危險”的C++代碼:

void?function(?void?)
{
????char*?str?=?new?char[100];
????delete[]?str;
????//?Do?something
????strcpy(?str,?"Dangerous!!"?);
}

之所以說其危險,是因為這是一段完全合乎語法的代碼,編譯的時候完美得一點錯誤也不會有,然而當(dāng)運行到strcpy一句的時候,問題就會出現(xiàn),因為在這之前,str的空間已經(jīng)被delete掉了,所以strcpy當(dāng)然不會成功。對于這種類似的情況,在林銳博士的書中有過介紹,稱其為“野指針”。

那么,諸位有沒有見過安全的“野指針”呢?下面請看我的一段C++程序,靈感來自CSDN上的一次討論。在此,我只需要C++的“類”,C++的其余一概不需要,因此我沒有使用任何的C++標準庫,連輸出都是用printf完成的。

#include?<stdio.h>

class?CTestClass
{
public:
????CTestClass(?void?);
????int?m_nInteger;
????void?Function(?void?);
};

CTestClass::CTestClass(?void?)
{
????m_nInteger?=?0;
}

void?CTestClass::Function(?void?)
{
????printf(?"This?is?a?test?function.\n"?);
}

void?main(?void?)
{
????CTestClass*?p?=?new?CTestClass;
????delete?p;
????p->Function();
}

OK,程序到此為止,諸位可以編譯運行一下看看結(jié)果如何。你也許會驚異地發(fā)現(xiàn):沒有任何的出錯信息,屏幕上竟然乖乖地出現(xiàn)了這么一行字符串:

This is a test function.

奇怪嗎?不要急,還有更奇怪的呢,你可以把主函數(shù)中加上一句更不可理喻的:

((CTestClass*)NULL)->Function();

這仍然沒有問題??!

我這還有呢,哈哈。現(xiàn)在你在主函數(shù)中這么寫,倘說上一句不可理喻,那么以下可以叫做無法無天了:

int?i?=?888;
CTestClass*?p2?=?(CTestClass*)&i;
p2->Function();

你看到了什么?是的,“This is a test function.”如約而至,沒有任何的錯誤。

你也許要問為什么,但是在我解答你之前,請你在主函數(shù)中加入如下代碼:

printf(?"%d,?%d",?sizeof(?CTestClass?),?sizeof(?int?)?);

這時你就會看到真相了:輸出結(jié)果是——得到的兩個十進制數(shù)相等。對,由sizeof得到的CTestClass的大小其實就是它的成員m_nInteger的大小。亦即是說,對于CTestClass的一個實例化的對象(設(shè)為a)而言,只有a.m_nInteger是屬于a這個對象的,而a.Function()卻是屬于CTestClass這個類的。所以以上看似危險的操作其實都是可行且無誤的。

現(xiàn)在你明白為什么我的“野指針”是安全的了,那么以下我所列出的,就是在什么情況下,我的“野指針”不安全:

  1. 在成員函數(shù)Function中對成員變量m_nInteger進行操作;
  2. 將成員函數(shù)Function聲明為虛函數(shù)(virtual)。

以上的兩種情況,目的就是強迫野指針使用屬于自己的東西導(dǎo)致不安全,比如第一種情況中操作本身的m_nInteger,第二種情況中變?yōu)樘摵瘮?shù)的Function成為了屬于對象的函數(shù)(這一點可以從sizeof看出來)。

其實,安全的野指針在實際的程序設(shè)計中是幾乎毫無用處的。我寫這一篇文章,意圖并不是像孔乙己一樣去琢磨回字有幾種寫法,而是想通過這個小例子向諸位寫明白C++的對象實例化本質(zhì),希望大家不但要明白what和how,更要明白why。李馬二零零三年二月二十日作于自宅。


關(guān)于成員函數(shù)CTestClass::Function的補充說明

這個函數(shù)是一個普通的成員函數(shù),它在編譯器的處理下,會成為類似如下的代碼:

void?Function(?const?CTestClass?*?this?)?//?①
{
????printf("This?is?a?test?function.\n");
}

那么p->Function();一句將被編譯器解釋為:

Function( p );

這就是說,普通的成員函數(shù)必須經(jīng)由一個對象來調(diào)用(經(jīng)由this指針激活②)。那么由上例的delete之后,p指針將會指向一個無效的地址,然而p本身是一個有效的變量,因此編譯能夠通過。并且在編譯通過之后,由于CTestClass::Function的函數(shù)體內(nèi)并未對這個傳入的this指針進行任何的操作,所以在這里,“野指針”便成了一個看似安全的東西。

然而若這樣改寫CTestClass::Function:

void?CTestClass::Function(?void?)
{
????m_nInteger?=?0;
}

那么它將會被編譯器解釋為:

void?Function(?const?CTestClass?*?this?)
{
????this->m_nInteger?=?0;
}

你看到了,在p->Function();的時候,系統(tǒng)將會嘗試在傳入的這個無效地址中尋找m_nInteger成員并將其賦值為0,剩下的我不用說了——非法操作出現(xiàn)了。

至于virtual虛函數(shù),如果在類定義之中將CTestClass聲明為虛函數(shù):

class?CTestClass
{
public:
????//?...
????virtual?void?Function(?void?);
};

那么C++在構(gòu)建CTestClass類的對象模型時,將會為之分配一個虛函數(shù)表vptr(可以從sizeof看出來)。vptr是一個指針,它指向一個函數(shù)指針的數(shù)組,數(shù)組中的成員即是在CTestClass中聲明的所有虛函數(shù)。在調(diào)用虛函數(shù)的時候,必須經(jīng)由這個vptr,這也就是為什么虛函數(shù)較之普通成員函數(shù)要消耗一些成本的緣故。以本例而言,p->Function();一句將被編譯器解釋為:

(*p->vptr[1])(?p?);?//?調(diào)用vptr表中索引號為1的函數(shù)(即Function)③

上面的代碼已經(jīng)說明了,如果p指向一個無效的地址,那么必然會有非法操作。

備注:

①關(guān)于函數(shù)的命名,我采用了原名而沒有變化。事實上編譯器為了避免函數(shù)重載造成的重名情況,會對函數(shù)的名字進行處理,使之成為獨一無二的名稱。
②將成員函數(shù)聲明為static,可以使成員函數(shù)不經(jīng)由this指針便可調(diào)用。
③vptr表中,索引號0為類的type_info。



青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            毛片av中文字幕一区二区| 欧美伦理a级免费电影| 国产精品美女久久久久aⅴ国产馆| 亚洲精品免费电影| 亚洲国产导航| 欧美精品在线一区二区| aa成人免费视频| 亚洲性图久久| 国内精品久久久久影院薰衣草 | 欧美日韩精品三区| 亚洲私拍自拍| 西西人体一区二区| 亚洲电影免费观看高清完整版| 欧美成人激情视频免费观看| 欧美成人资源| 欧美亚洲一区| 久久综合九色欧美综合狠狠| 亚洲免费观看| 欧美一级二区| 亚洲精品国产精品乱码不99| 一本久久a久久免费精品不卡| 国产美女精品人人做人人爽| 男女视频一区二区| 国产精品国产三级欧美二区| 久久精品国产亚洲一区二区三区| 久久免费国产精品| 亚洲一区二区三区精品动漫| 羞羞漫画18久久大片| 亚洲九九爱视频| 欧美一级午夜免费电影| 99xxxx成人网| 久久精品国产一区二区三区免费看| 亚洲精品日韩一| 香蕉久久夜色精品国产| av不卡在线| 久久影音先锋| 久久国产精品黑丝| 欧美日韩一区二区在线 | 夜夜爽av福利精品导航| 午夜精品理论片| 亚洲视频免费看| 噜噜噜91成人网| 亚洲综合激情| 欧美精品日韩精品| 免费成人你懂的| 国产一区导航| 亚洲专区一区二区三区| 亚洲视频在线视频| 欧美激情按摩在线| 欧美 日韩 国产 一区| 国产婷婷成人久久av免费高清| 亚洲精品视频在线看| 亚洲人成啪啪网站| 裸体一区二区| 免费看的黄色欧美网站| 国产一区二区三区精品欧美日韩一区二区三区 | 亚洲精品日韩激情在线电影| 国内精品亚洲| 欧美在线啊v一区| 欧美一区在线直播| 国产精品夜夜夜一区二区三区尤| 亚洲国产精品第一区二区| 精品av久久707| 久久国产夜色精品鲁鲁99| 欧美影视一区| 国产亚洲观看| 久久精品99国产精品日本| 欧美一区久久| 国产一区日韩二区欧美三区| 欧美一区91| 久久中文在线| 亚洲国产成人在线播放| 美日韩在线观看| 亚洲国产99精品国自产| 亚洲精品国产视频| 欧美激情一区在线| 日韩天堂在线观看| 亚洲欧美大片| 国产一区二区观看| 久久免费视频网站| 欧美激情在线有限公司| 日韩午夜av在线| 欧美午夜不卡在线观看免费 | 久久精品成人一区二区三区蜜臀| 国产片一区二区| 久久精品天堂| 亚洲电影欧美电影有声小说| 日韩亚洲视频在线| 国产精品久线观看视频| 性色一区二区三区| 欧美激情网友自拍| 亚洲综合成人在线| 狠狠色综合网| 欧美另类女人| 亚洲欧美日韩在线高清直播| 久久久久综合网| 日韩网站在线观看| 国产美女高潮久久白浆| 免费在线亚洲| 午夜免费在线观看精品视频| 免费不卡在线视频| 亚洲午夜精品网| 136国产福利精品导航| 欧美日韩亚洲三区| 久久久精品动漫| 亚洲午夜电影网| 亚洲大片av| 久久九九免费视频| 在线视频亚洲| 亚洲电影一级黄| 国产精品视频999| 欧美成人一区二区三区| 欧美一区二区三区啪啪| 亚洲欧洲在线观看| 久久久久久成人| 亚洲先锋成人| 亚洲区在线播放| 国产精品综合色区在线观看| 久久这里只有| 欧美一区二区三区婷婷月色| 91久久国产综合久久91精品网站| 久久久久久69| 欧美一区二区视频免费观看| 亚洲美女诱惑| 亚洲人成网站999久久久综合| 国产欧美日韩视频一区二区三区| 欧美精品在线观看91| 久久偷窥视频| 久久精品亚洲热| 先锋a资源在线看亚洲| 亚洲深夜福利在线| 日韩一区二区精品在线观看| 欧美风情在线| 欧美成人午夜77777| 老司机一区二区三区| 久久成人免费| 欧美一区二区三区的| 亚洲在线免费| 亚洲欧美激情一区二区| 中文日韩欧美| 亚洲男人av电影| 亚洲欧美怡红院| 香蕉免费一区二区三区在线观看 | 久久福利一区| 久久国产日韩| 久久久久久久综合| 久久亚洲国产成人| 久久久国产亚洲精品| 久久视频在线看| 蜜臀91精品一区二区三区| 久热综合在线亚洲精品| 久久亚洲私人国产精品va媚药| 久久精品论坛| 欧美aⅴ99久久黑人专区| 美女免费视频一区| 欧美成人一区二区三区在线观看| 欧美第十八页| 亚洲美女毛片| 亚洲欧美国产精品va在线观看| 午夜精品国产更新| 久久久久**毛片大全| 久久亚洲一区二区| 欧美高清视频在线| 国产精品xnxxcom| 国内精品免费午夜毛片| **网站欧美大片在线观看| 亚洲精品一区二区三区在线观看| 日韩视频一区二区三区在线播放免费观看 | 美女图片一区二区| 欧美久久九九| 国产乱肥老妇国产一区二| 精品69视频一区二区三区| 亚洲国产日韩在线一区模特| 一卡二卡3卡四卡高清精品视频| 亚洲欧美日韩一区在线| 老司机免费视频一区二区三区 | 亚洲婷婷免费| 久久免费偷拍视频| 亚洲片国产一区一级在线观看| 亚洲图片欧美一区| 久久蜜桃精品| 国产精品美女黄网| 亚洲国产精品成人va在线观看| 一区二区日韩精品| 麻豆国产精品va在线观看不卡| 亚洲精品美女久久7777777| 亚洲欧美欧美一区二区三区| 欧美91大片| 国产一区三区三区| 这里只有精品视频| 欧美成人免费观看| 亚洲在线观看视频网站| 免费成人网www| 国产最新精品精品你懂的| 在线亚洲一区二区| 亚洲国产成人91精品| 性久久久久久| 欧美日韩精品在线| 亚洲欧洲一二三| 免费成人av|