• <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>

            洛譯小筑

            別來(lái)無(wú)恙,我的老友…
            隨筆 - 45, 文章 - 0, 評(píng)論 - 172, 引用 - 0
            數(shù)據(jù)加載中……

            [ECPP讀書(shū)筆記 條目16] 互相關(guān)聯(lián)的new和delete要使用同樣的形式

            下面的情景有什么不妥之處呢?

            std::string *stringArray = new std::string[100];

            ...

            delete stringArray;

            一切似乎都按部就班,new語(yǔ)句與delete相匹配。然而,這卻是大錯(cuò)特錯(cuò)的。這段程序?qū)⒊霈F(xiàn)未定義行為。最起碼的是,由于該stringArray所指向的100個(gè)string對(duì)象中的99個(gè)沒(méi)有被析構(gòu)函數(shù)所析構(gòu),它們將很有可能不會(huì)被銷(xiāo)毀。

            當(dāng)你使用了一個(gè)new語(yǔ)句時(shí)(也可以說(shuō),使用new動(dòng)態(tài)創(chuàng)建了一個(gè)對(duì)象),將會(huì)發(fā)生兩件事情。第一,分配內(nèi)存(通過(guò)一個(gè)名為operator new的函數(shù),參見(jiàn)條目49和51)。第二,為這段內(nèi)存調(diào)用一個(gè)或多個(gè)構(gòu)造函數(shù)。當(dāng)你使用了一個(gè)delete語(yǔ)句時(shí),將會(huì)發(fā)生另外兩件事情:第一,為分配的內(nèi)存調(diào)用一個(gè)或多個(gè)析構(gòu)函數(shù)。第二,釋放內(nèi)存(通過(guò)operator delete函數(shù)實(shí)現(xiàn),參見(jiàn)條目51)。delete的關(guān)鍵問(wèn)題是:內(nèi)存中存在多少需要?jiǎng)h除的對(duì)象呢?答案取決于需要調(diào)用多少析構(gòu)函數(shù)。

            實(shí)際上,答案比這還要簡(jiǎn)單:你正在刪除的指針是指向一個(gè)單獨(dú)的對(duì)象,還是一組對(duì)象?這個(gè)問(wèn)題很關(guān)鍵,因?yàn)闉閱蝹€(gè)對(duì)象分配的內(nèi)存與為一系列對(duì)象分配的內(nèi)存在形式上有本質(zhì)的不同。具體地說(shuō),為數(shù)組分配的內(nèi)存通常要保存數(shù)組的大小,這就使得delete很容易知道需要調(diào)用多少次析構(gòu)函數(shù)。為單個(gè)對(duì)象分配的內(nèi)存則不保存這一信息。你可以將這一差別想象成下邊圖中的樣子,其中n是數(shù)組的大小:

            當(dāng)然這僅僅是一個(gè)示例,并沒(méi)有強(qiáng)制指標(biāo)要求編譯器以這種形式實(shí)現(xiàn),盡管許多編譯器確實(shí)是這樣的。

            當(dāng)你對(duì)一個(gè)指針使用delete時(shí),如何讓delete知道這一指針是否存在數(shù)組信息呢?這里只有一種方法,那就是親自告訴它。如果你在delete與指針名之間添加一對(duì)中括號(hào),則delete便認(rèn)為這一指針指向一個(gè)數(shù)組。否則將以單一對(duì)象處理。

            std::string *stringPtr1 = new std::string;

            std::string *stringPtr2 = new std::string[100];

            ...

             

            delete stringPtr1;                 // 刪除一個(gè)對(duì)象

            delete [] stringPtr2;              // 刪除一個(gè)對(duì)象數(shù)組

            如果你為stringPtr1使用“[]”時(shí)將會(huì)發(fā)生什么呢?我們說(shuō),會(huì)導(dǎo)致未定義行為。假設(shè)使用上面的內(nèi)存分配形式,delete將會(huì)讀入一些內(nèi)存信息,并且將其理解為數(shù)組的長(zhǎng)度,然后便開(kāi)始調(diào)用這么多的析構(gòu)函數(shù),此時(shí)delete不僅忽視了它正在操作的內(nèi)存上保存的并不是數(shù)組,同時(shí)它“辛辛苦苦”析構(gòu)的東西很有可能都不是它所能操作的類(lèi)型。

            如果你不為stringPtr2使用“[]”將會(huì)發(fā)生什么呢?同樣會(huì)導(dǎo)致未定義行為。你可以看到由于它沒(méi)有調(diào)用足夠的析構(gòu)函數(shù),將造成內(nèi)存泄漏。同時(shí),對(duì)于內(nèi)建數(shù)據(jù)類(lèi)型,諸如int等,盡管它們沒(méi)有析構(gòu)函數(shù),這個(gè)做法也將帶來(lái)未定義行為(有時(shí)是有害的)。

            這里的規(guī)則很簡(jiǎn)單:如果你在一個(gè)new語(yǔ)句中使用了[],那么你必須在相關(guān)的delete語(yǔ)句中也使用[]。如果你在一個(gè)new語(yǔ)句中沒(méi)有使用[],那么在相關(guān)的delete語(yǔ)句中也不應(yīng)使用[]

            有時(shí)候你會(huì)編寫(xiě)這樣的類(lèi):它們包含用來(lái)動(dòng)態(tài)分配內(nèi)存的指針,并且提供多個(gè)構(gòu)造函數(shù)。此時(shí)你需要時(shí)刻注意遵守上面的規(guī)則。在所有的構(gòu)造函數(shù)中,你必須使用一致格式的new來(lái)初始化指針成員。如果你不這樣做,你怎么能知道析構(gòu)函數(shù)中delete需要用什么樣的格式呢?

            如果你傾向于使用typedef,那么這一規(guī)則同樣值得你注意,因?yàn)樗馕吨寒?dāng)你使用了new來(lái)創(chuàng)建typedef類(lèi)型的對(duì)象時(shí),至于應(yīng)該使用delete語(yǔ)句的哪種形式,typedef的作者必須事先做出說(shuō)明。請(qǐng)看下邊的示例:

            typedef std::string AddressLines[4]    // 每個(gè)人的地址有4行,

                                               // 每行都是一個(gè)字符串

            由于AddressLines是一個(gè)數(shù)組, 如果這樣使用了new

            std::string *pal = new AddressLines;   // 請(qǐng)注意“new AddressLines

                                               // 返回一個(gè)string*

                                               // 與“new string[4]”完全一樣

            那么delete就必須使用數(shù)組的格式:

            delete pal;                        // 將出現(xiàn)未定義行為!

            delete [] pal;                     // 工作正常

            為了避免此類(lèi)混淆,請(qǐng)不要使用typedef來(lái)定義數(shù)組。這十分簡(jiǎn)單,因?yàn)镃++標(biāo)準(zhǔn)庫(kù)(參見(jiàn)條目54)中包含了stringvector,使用這些模板可以擺脫動(dòng)態(tài)分配數(shù)組的煩惱。比如說(shuō),在這里,AddressLines可以定義為一個(gè)字符串的向量,也就是vector<string>類(lèi)型。

            時(shí)刻牢記

            如果你在一個(gè)new語(yǔ)句中使用了[],那么你必須要在相關(guān)的delete語(yǔ)句中使用[]。如果你在new語(yǔ)句中沒(méi)有使用[],那么在相關(guān)的delete語(yǔ)句中一定不要出現(xiàn)[]

            posted on 2007-05-14 22:15 ★ROY★ 閱讀(1108) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): Effective C++

            国产精品美女久久久久| 久久精品99无色码中文字幕| 久久成人国产精品一区二区| 国产69精品久久久久777| 欧美激情一区二区久久久| 91久久精品国产91性色也| 国产激情久久久久影院老熟女| 国产精品天天影视久久综合网| 国产91久久精品一区二区| 精品999久久久久久中文字幕| 久久精品国产69国产精品亚洲| 国产精品久久精品| 99久久伊人精品综合观看| 国产亚洲色婷婷久久99精品91| 久久无码精品一区二区三区| 久久一区二区三区免费| 波多野结衣久久| 亚洲级αV无码毛片久久精品| 久久不见久久见免费视频7| 久久青青草原精品影院| 久久久久噜噜噜亚洲熟女综合| 热久久最新网站获取| 嫩草伊人久久精品少妇AV| 99久久精品无码一区二区毛片| 久久久久亚洲av成人无码电影| 亚洲国产成人久久精品99| 亚洲色婷婷综合久久| 色综合久久中文色婷婷| 亚洲人成电影网站久久| 99久久国语露脸精品国产| 久久精品国产黑森林| 国产成人精品综合久久久久| 热re99久久精品国99热| 日本亚洲色大成网站WWW久久| 亚洲AV日韩AV天堂久久| 久久免费国产精品| 久久精品aⅴ无码中文字字幕重口| 一本久久久久久久| 久久久久久九九99精品| 看全色黄大色大片免费久久久| 99久久精品费精品国产一区二区 |