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

            洛譯小筑

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

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

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

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

            ...

            delete stringArray;

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

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

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

            當然這僅僅是一個示例,并沒有強制指標要求編譯器以這種形式實現(xiàn),盡管許多編譯器確實是這樣的。

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

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

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

            ...

             

            delete stringPtr1;                 // 刪除一個對象

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

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

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

            這里的規(guī)則很簡單:如果你在一個new語句中使用了[],那么你必須在相關的delete語句中也使用[]。如果你在一個new語句中沒有使用[],那么在相關的delete語句中也不應使用[]。

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

            如果你傾向于使用typedef,那么這一規(guī)則同樣值得你注意,因為它意味著:當你使用了new來創(chuàng)建typedef類型的對象時,至于應該使用delete語句的哪種形式,typedef的作者必須事先做出說明。請看下邊的示例:

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

                                               // 每行都是一個字符串

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

            std::string *pal = new AddressLines;   // 請注意“new AddressLines

                                               // 返回一個string*

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

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

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

            delete [] pal;                     // 工作正常

            為了避免此類混淆,請不要使用typedef來定義數(shù)組。這十分簡單,因為C++標準庫(參見條目54)中包含了stringvector,使用這些模板可以擺脫動態(tài)分配數(shù)組的煩惱。比如說,在這里,AddressLines可以定義為一個字符串的向量,也就是vector<string>類型。

            時刻牢記

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

            posted on 2007-05-14 22:15 ★ROY★ 閱讀(1107) 評論(0)  編輯 收藏 引用 所屬分類: Effective C++

            久久精品国产精品亚洲下载| 精品久久人人爽天天玩人人妻| 久久亚洲国产精品成人AV秋霞| 久久婷婷色综合一区二区| 2019久久久高清456| 久久精品国产亚洲AV香蕉| 很黄很污的网站久久mimi色| 要久久爱在线免费观看| 狠狠色丁香久久综合婷婷| 香蕉久久夜色精品国产2020| 久久国产精品久久久| 久久精品国产亚洲AV香蕉| 久久久久久毛片免费看| 久久水蜜桃亚洲av无码精品麻豆| 久久久久久青草大香综合精品 | 青青青青久久精品国产| 久久99热这里只有精品66| 日本福利片国产午夜久久| 99久久国产精品免费一区二区 | 国产aⅴ激情无码久久| 国产91色综合久久免费| 久久久久精品国产亚洲AV无码| 国产精品成人99久久久久 | 狠狠色丁香婷综合久久| 久久夜色精品国产欧美乱| 久久综合色之久久综合| 久久久久成人精品无码中文字幕 | 亚洲精品美女久久久久99| 日韩欧美亚洲综合久久影院Ds| 久久综合九色综合精品| 精品少妇人妻av无码久久| 99久久精品国产一区二区| 99久久这里只精品国产免费| 久久亚洲av无码精品浪潮| 国内精品久久久久国产盗摄| 久久精品国产99国产精品澳门 | 72种姿势欧美久久久久大黄蕉| 性做久久久久久久| 无码精品久久久天天影视| 亚洲精品乱码久久久久久自慰 | 97久久精品无码一区二区天美|